// Copyright (c) 2020 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 #include #include #include #include #include #include #include #include namespace PaddleX { // Object for storing all preprocessed data class ImageBlob { public: // Original image height and width std::vector ori_im_size_ = std::vector(2); // Newest image height and width after process std::vector new_im_size_ = std::vector(2); // Image height and width before resize std::vector> im_size_before_resize_; // Reshape order std::vector reshape_order_; // Resize scale float scale = 1.0; // Buffer for image data after preprocessing std::vector im_data_; void clear() { ori_im_size_.clear(); new_im_size_.clear(); im_size_before_resize_.clear(); reshape_order_.clear(); im_data_.clear(); } }; // Abstraction of preprocessing opration class class Transform { public: virtual void Init(const YAML::Node& item) = 0; virtual bool Run(cv::Mat* im, ImageBlob* data) = 0; virtual void SetPaddingSize(int max_h, int max_w) {} }; class Normalize : public Transform { public: virtual void Init(const YAML::Node& item) { mean_ = item["mean"].as>(); std_ = item["std"].as>(); } virtual bool Run(cv::Mat* im, ImageBlob* data); private: std::vector mean_; std::vector std_; }; class ResizeByShort : public Transform { public: virtual void Init(const YAML::Node& item) { short_size_ = item["short_size"].as(); if (item["max_size"].IsDefined()) { max_size_ = item["max_size"].as(); } else { max_size_ = -1; } } virtual bool Run(cv::Mat* im, ImageBlob* data); private: float GenerateScale(const cv::Mat& im); int short_size_; int max_size_; }; class ResizeByLong : public Transform { public: virtual void Init(const YAML::Node& item) { long_size_ = item["long_size"].as(); } virtual bool Run(cv::Mat* im, ImageBlob* data); private: int long_size_; }; class Resize : public Transform { public: virtual void Init(const YAML::Node& item) { if (item["target_size"].IsScalar()) { height_ = item["target_size"].as(); width_ = item["target_size"].as(); interp_ = item["interp"].as(); } else if (item["target_size"].IsSequence()) { std::vector target_size = item["target_size"].as>(); width_ = target_size[0]; height_ = target_size[1]; } if (height_ <= 0 || width_ <= 0) { std::cerr << "[Resize] target_size should greater than 0" << std::endl; exit(-1); } } virtual bool Run(cv::Mat* im, ImageBlob* data); private: int height_; int width_; std::string interp_; }; class CenterCrop : public Transform { public: virtual void Init(const YAML::Node& item) { if (item["crop_size"].IsScalar()) { height_ = item["crop_size"].as(); width_ = item["crop_size"].as(); } else if (item["crop_size"].IsSequence()) { std::vector crop_size = item["crop_size"].as>(); width_ = crop_size[0]; height_ = crop_size[1]; } } virtual bool Run(cv::Mat* im, ImageBlob* data); private: int height_; int width_; }; class Padding : public Transform { public: virtual void Init(const YAML::Node& item) { if (item["coarsest_stride"].IsDefined()) { coarsest_stride_ = item["coarsest_stride"].as(); if (coarsest_stride_ < 1) { std::cerr << "[Padding] coarest_stride should greater than 0" << std::endl; exit(-1); } } if (item["target_size"].IsDefined()) { if (item["target_size"].IsScalar()) { width_ = item["target_size"].as(); height_ = item["target_size"].as(); } else if (item["target_size"].IsSequence()) { width_ = item["target_size"].as>()[0]; height_ = item["target_size"].as>()[1]; } } } virtual bool Run(cv::Mat* im, ImageBlob* data); virtual void SetPaddingSize(int max_h, int max_w); private: int coarsest_stride_ = -1; int width_ = 0; int height_ = 0; int max_height_ = 0; int max_width_ = 0; }; class Transforms { public: void Init(const YAML::Node& node, bool to_rgb = true); std::shared_ptr CreateTransform(const std::string& name); bool Run(cv::Mat* im, ImageBlob* data); void SetPaddingSize(int max_h, int max_w); private: std::vector> transforms_; bool to_rgb_ = true; int max_h_ = 0; int max_w_ = 0; }; } // namespace PaddleX