Преглед изворни кода

support mutil-channel in deploy/cpp

FlyingQianMM пре 5 година
родитељ
комит
3bb6a7793a
2 измењених фајлова са 65 додато и 11 уклоњено
  1. 31 0
      deploy/cpp/include/paddlex/transforms.h
  2. 34 11
      deploy/cpp/src/transforms.cpp

+ 31 - 0
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::vector<float>>();
     std_ = item["std"].as<std::vector<float>>();
+    if (item["min_val"].IsDefined()) {
+      min_val_ = item["min_val"].as<std::vector<float>>();
+    } else {
+      min_val_ = std::vector<float>(0., mean_.size());
+    }
+    if (item["max_val"].IsDefined()) {
+      max_val_ = item["max_val"].as<std::vector<float>>();
+    } else {
+      max_val_ = std::vector<float>(255., mean_.size());
+    }
   }
 
   virtual bool Run(cv::Mat* im, ImageBlob* data);
@@ -89,6 +99,8 @@ class Normalize : public Transform {
  private:
   std::vector<float> mean_;
   std::vector<float> std_;
+  std::vector<float> min_val_;
+  std::vector<float> max_val_;
 };
 
 /*
@@ -229,6 +241,25 @@ class Padding : public Transform {
   int height_ = 0;
   std::vector<float> 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<std::vector<float>>();
+    max_val_ = item["max_val"].as<std::vector<float>>();
+  }
+
+  virtual bool Run(cv::Mat* im, ImageBlob* data);
+
+ private:
+  std::vector<float> min_val_;
+  std::vector<float> max_val_;
+};
+
 /*
  * @brief
  * This class is transform operations manager. It stores all neccessary

+ 34 - 11
deploy/cpp/src/transforms.cpp

@@ -30,14 +30,14 @@ std::map<std::string, int> 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<cv::Vec3f>(h, w)[0] =
-          (im->at<cv::Vec3f>(h, w)[0] / 255.0 - mean_[0]) / std_[0];
-      im->at<cv::Vec3f>(h, w)[1] =
-          (im->at<cv::Vec3f>(h, w)[1] / 255.0 - mean_[1]) / std_[1];
-      im->at<cv::Vec3f>(h, w)[2] =
-          (im->at<cv::Vec3f>(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<cv::Vec3f>(h, w)[c] =
+            ((im->at<cv::Vec3f>(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<cv::Mat> 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<cv::Vec3f>(h, w)[c] < min_val_[c]) {
+          im->at<cv::Vec3f>(h, w)[c] = min_val_[c];
+        }
+        if (im->at<cv::Vec3f>(h, w)[c] > max_val_[c]) {
+          im->at<cv::Vec3f>(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;