From 3bb6a7793a79e1bb02a85da928db34d4f9da8c0e Mon Sep 17 00:00:00 2001 From: FlyingQianMM <245467267@qq.com> Date: Mon, 14 Sep 2020 09:44:31 +0000 Subject: [PATCH] support mutil-channel in deploy/cpp --- deploy/cpp/include/paddlex/transforms.h | 31 +++++++++++++++++ deploy/cpp/src/transforms.cpp | 45 +++++++++++++++++++------ 2 files changed, 65 insertions(+), 11 deletions(-) diff --git a/deploy/cpp/include/paddlex/transforms.h b/deploy/cpp/include/paddlex/transforms.h index b99abf9..8b26581 100644 --- a/deploy/cpp/include/paddlex/transforms.h +++ b/deploy/cpp/include/paddlex/transforms.h @@ -82,6 +82,16 @@ class Normalize : public Transform { virtual void Init(const YAML::Node& item) { mean_ = item["mean"].as>(); std_ = item["std"].as>(); + if (item["min_val"].IsDefined()) { + min_val_ = item["min_val"].as>(); + } else { + min_val_ = std::vector(0., mean_.size()); + } + if (item["max_val"].IsDefined()) { + max_val_ = item["max_val"].as>(); + } else { + max_val_ = std::vector(255., mean_.size()); + } } virtual bool Run(cv::Mat* im, ImageBlob* data); @@ -89,6 +99,8 @@ class Normalize : public Transform { private: std::vector mean_; std::vector std_; + std::vector min_val_; + std::vector max_val_; }; /* @@ -229,6 +241,25 @@ class Padding : public Transform { int height_ = 0; std::vector im_value_; }; + +/* + * @brief + * This class execute clip operation on image matrix + * */ +class Clip : public Transform { + public: + virtual void Init(const YAML::Node& item) { + min_val_ = item["min_val"].as>(); + max_val_ = item["max_val"].as>(); + } + + virtual bool Run(cv::Mat* im, ImageBlob* data); + + private: + std::vector min_val_; + std::vector max_val_; +}; + /* * @brief * This class is transform operations manager. It stores all neccessary diff --git a/deploy/cpp/src/transforms.cpp b/deploy/cpp/src/transforms.cpp index dfbe6d9..76dafd5 100644 --- a/deploy/cpp/src/transforms.cpp +++ b/deploy/cpp/src/transforms.cpp @@ -30,14 +30,14 @@ std::map interpolations = {{"LINEAR", cv::INTER_LINEAR}, {"LANCZOS4", cv::INTER_LANCZOS4}}; bool Normalize::Run(cv::Mat* im, ImageBlob* data) { - for (int h = 0; h < im->rows; h++) { - for (int w = 0; w < im->cols; w++) { - im->at(h, w)[0] = - (im->at(h, w)[0] / 255.0 - mean_[0]) / std_[0]; - im->at(h, w)[1] = - (im->at(h, w)[1] / 255.0 - mean_[1]) / std_[1]; - im->at(h, w)[2] = - (im->at(h, w)[2] / 255.0 - mean_[2]) / std_[2]; + for (int c = 0; c < im->channels(); c++) { + float range_val = max_val_[c] - min_val_[c]; + for (int h = 0; h < im->rows; h++) { + for (int w = 0; w < im->cols; w++) { + im->at(h, w)[c] = + ((im->at(h, w)[c] - min_val_[c]) / range_val - + mean_[c]) / std_[c]; + } } } return true; @@ -113,9 +113,16 @@ bool Padding::Run(cv::Mat* im, ImageBlob* data) { << ", but they should be greater than 0." << std::endl; return false; } - cv::Scalar value = cv::Scalar(im_value_[0], im_value_[1], im_value_[2]); - cv::copyMakeBorder( - *im, *im, 0, padding_h, 0, padding_w, cv::BORDER_CONSTANT, value); + std::vector padded_im_per_channel; + for (size_t i = 0; i < im->channels(); i++) { + const cv::Mat per_channel = cv::Mat(im->size(), CV_32FC1, im_value_[i]); + padded_im_per_channel.push_back(per_channel); + } + cv::Mat padded_im; + cv::merge(padded_im_per_channel, padded_im); + cv::Rect im_roi = cv::Rect(0, 0, im->cols, im->rows); + im->copyTo(padded_im(im_roi)); + *im = padded_im; data->new_im_size_[0] = im->rows; data->new_im_size_[1] = im->cols; return true; @@ -163,6 +170,22 @@ bool Resize::Run(cv::Mat* im, ImageBlob* data) { return true; } +bool Clip::Run(cv::Mat* im, ImageBlob* data) { + for (int h = 0; h < im->rows; h++) { + for (int w = 0; w < im->cols; w++) { + for (int c = 0; c < im->channels(); c++) { + if (im->at(h, w)[c] < min_val_[c]) { + im->at(h, w)[c] = min_val_[c]; + } + if (im->at(h, w)[c] > max_val_[c]) { + im->at(h, w)[c] = max_val_[c]; + } + } + } + } + return true; +} + void Transforms::Init(const YAML::Node& transforms_node, bool to_rgb) { transforms_.clear(); to_rgb_ = to_rgb; -- GitLab