Browse Source

refine cpp seg deploy

will-jl944 4 years ago
parent
commit
3758a44928

+ 6 - 6
deploy/cpp/model_deploy/ppseg/include/seg_postprocess.h

@@ -39,14 +39,14 @@ class SegPostprocess : public BasePostprocess {
                    const std::vector<ShapeInfo>& shape_infos,
                    const std::vector<ShapeInfo>& shape_infos,
                    std::vector<Result>* results, int thread_num = 1);
                    std::vector<Result>* results, int thread_num = 1);
 
 
-  void RestoreSegMap(const ShapeInfo& shape_info,
-                     cv::Mat* label_mat,
-                     cv::Mat* score_mat,
-                     SegResult* result);
+  void RestoreSegMap(const ShapeInfo& shape_info, cv::Mat* label_mat,
+                     cv::Mat* score_mat, SegResult* result);
 
 
-  bool RunV2(const DataBlob& outputs,
-             const std::vector<ShapeInfo>& shape_infos,
+  bool RunV2(const DataBlob& outputs, const std::vector<ShapeInfo>& shape_infos,
              std::vector<Result>* results, int thread_num);
              std::vector<Result>* results, int thread_num);
+
+ private:
+  std::string version_;
 };
 };
 
 
 }  // namespace PaddleDeploy
 }  // namespace PaddleDeploy

+ 43 - 32
deploy/cpp/model_deploy/ppseg/src/seg_postprocess.cpp

@@ -12,24 +12,34 @@
 // See the License for the specific language governing permissions and
 // See the License for the specific language governing permissions and
 // limitations under the License.
 // limitations under the License.
 
 
-#include <time.h>
-
 #include "model_deploy/ppseg/include/seg_postprocess.h"
 #include "model_deploy/ppseg/include/seg_postprocess.h"
 
 
+#include <time.h>
+
 namespace PaddleDeploy {
 namespace PaddleDeploy {
 
 
 bool SegPostprocess::Init(const YAML::Node& yaml_config) {
 bool SegPostprocess::Init(const YAML::Node& yaml_config) {
+  if (yaml_config["version"].IsDefined() &&
+      yaml_config["toolkit"].as<std::string>() == "PaddleX") {
+    version_ = yaml_config["version"].as<std::string>();
+  } else {
+    version_ = "0.0.0"
+  }
   return true;
   return true;
 }
 }
 
 
 void SegPostprocess::RestoreSegMap(const ShapeInfo& shape_info,
 void SegPostprocess::RestoreSegMap(const ShapeInfo& shape_info,
-                                   cv::Mat* label_mat,
-                                   cv::Mat*  score_mat,
+                                   cv::Mat* label_mat, cv::Mat* score_mat,
                                    SegResult* result) {
                                    SegResult* result) {
   int ori_h = shape_info.shapes[0][1];
   int ori_h = shape_info.shapes[0][1];
   int ori_w = shape_info.shapes[0][0];
   int ori_w = shape_info.shapes[0][0];
+  int score_c = score_mat.channels();
   result->label_map.Resize({ori_h, ori_w});
   result->label_map.Resize({ori_h, ori_w});
-  result->score_map.Resize({ori_h, ori_w});
+  if (score_c == 1) {
+    result->score_map.Resize({ori_h, ori_w});
+  } else {
+    result->score_map.Resize({ori_h, ori_w, score_c});
+  }
 
 
   for (int j = shape_info.transforms.size() - 1; j > 0; --j) {
   for (int j = shape_info.transforms.size() - 1; j > 0; --j) {
     std::vector<int> last_shape = shape_info.shapes[j - 1];
     std::vector<int> last_shape = shape_info.shapes[j - 1];
@@ -38,13 +48,13 @@ void SegPostprocess::RestoreSegMap(const ShapeInfo& shape_info,
         shape_info.transforms[j] == "ResizeByShort" ||
         shape_info.transforms[j] == "ResizeByShort" ||
         shape_info.transforms[j] == "ResizeByLong") {
         shape_info.transforms[j] == "ResizeByLong") {
       if (last_shape[0] != label_mat->cols ||
       if (last_shape[0] != label_mat->cols ||
-            last_shape[1] != label_mat->rows) {
+          last_shape[1] != label_mat->rows) {
         cv::resize(*label_mat, *label_mat,
         cv::resize(*label_mat, *label_mat,
-                cv::Size(last_shape[0], last_shape[1]),
-                0, 0, cv::INTER_NEAREST);
+                   cv::Size(last_shape[0], last_shape[1]), 0, 0,
+                   cv::INTER_NEAREST);
         cv::resize(*score_mat, *score_mat,
         cv::resize(*score_mat, *score_mat,
-                cv::Size(last_shape[0], last_shape[1]),
-                0, 0, cv::INTER_LINEAR);
+                   cv::Size(last_shape[0], last_shape[1]), 0, 0,
+                   cv::INTER_LINEAR);
       }
       }
     } else if (shape_info.transforms[j] == "Padding") {
     } else if (shape_info.transforms[j] == "Padding") {
       if (last_shape[0] < label_mat->cols || last_shape[1] < label_mat->rows) {
       if (last_shape[0] < label_mat->cols || last_shape[1] < label_mat->rows) {
@@ -53,10 +63,10 @@ void SegPostprocess::RestoreSegMap(const ShapeInfo& shape_info,
       }
       }
     }
     }
   }
   }
-  result->label_map.data.assign(
-    label_mat->begin<uint8_t>(), label_mat->end<uint8_t>());
-  result->score_map.data.assign(
-    score_mat->begin<float>(), score_mat->end<float>());
+  result->label_map.data.assign(label_mat->begin<uint8_t>(),
+                                label_mat->end<uint8_t>());
+  result->score_map.data.assign(score_mat->begin<float>(),
+                                score_mat->end<float>());
 }
 }
 
 
 // ppseg version >= 2.1  shape = [b, w, h]
 // ppseg version >= 2.1  shape = [b, w, h]
@@ -69,17 +79,17 @@ bool SegPostprocess::RunV2(const DataBlob& output,
   std::vector<uint8_t> label_vector;
   std::vector<uint8_t> label_vector;
   if (output.dtype == INT64) {  // int64
   if (output.dtype == INT64) {  // int64
     const int64_t* output_data =
     const int64_t* output_data =
-          reinterpret_cast<const int64_t*>(output.data.data());
+        reinterpret_cast<const int64_t*>(output.data.data());
     std::transform(output_data, output_data + label_map_size * batch_size,
     std::transform(output_data, output_data + label_map_size * batch_size,
                    std::back_inserter(label_vector),
                    std::back_inserter(label_vector),
-                   [](int64_t x) { return (uint8_t)x;});
+                   [](int64_t x) { return (uint8_t)x; });
     label_data = reinterpret_cast<const uint8_t*>(label_vector.data());
     label_data = reinterpret_cast<const uint8_t*>(label_vector.data());
   } else if (output.dtype == INT32) {  // int32
   } else if (output.dtype == INT32) {  // int32
     const int32_t* output_data =
     const int32_t* output_data =
-          reinterpret_cast<const int32_t*>(output.data.data());
+        reinterpret_cast<const int32_t*>(output.data.data());
     std::transform(output_data, output_data + label_map_size * batch_size,
     std::transform(output_data, output_data + label_map_size * batch_size,
                    std::back_inserter(label_vector),
                    std::back_inserter(label_vector),
-                   [](int32_t x) { return (uint8_t)x;});
+                   [](int32_t x) { return (uint8_t)x; });
     label_data = reinterpret_cast<const uint8_t*>(label_vector.data());
     label_data = reinterpret_cast<const uint8_t*>(label_vector.data());
   } else if (output.dtype == INT8) {  // uint8
   } else if (output.dtype == INT8) {  // uint8
     label_data = reinterpret_cast<const uint8_t*>(output.data.data());
     label_data = reinterpret_cast<const uint8_t*>(output.data.data());
@@ -93,13 +103,13 @@ bool SegPostprocess::RunV2(const DataBlob& output,
     (*results)[i].model_type = "seg";
     (*results)[i].model_type = "seg";
     (*results)[i].seg_result = new SegResult();
     (*results)[i].seg_result = new SegResult();
     const uint8_t* current_start_ptr = label_data + i * label_map_size;
     const uint8_t* current_start_ptr = label_data + i * label_map_size;
-    cv::Mat score_mat(output.shape[1], output.shape[2],
-                      CV_32FC1, cv::Scalar(1.0));
-    cv::Mat label_mat(output.shape[1], output.shape[2],
-                      CV_8UC1, const_cast<uint8_t*>(current_start_ptr));
+    cv::Mat score_mat(output.shape[1], output.shape[2], CV_32FC1,
+                      cv::Scalar(1.0));
+    cv::Mat label_mat(output.shape[1], output.shape[2], CV_8UC1,
+                      const_cast<uint8_t*>(current_start_ptr));
 
 
-    RestoreSegMap(shape_infos[i], &label_mat,
-                 &score_mat, (*results)[i].seg_result);
+    RestoreSegMap(shape_infos[i], &label_mat, &score_mat,
+                  (*results)[i].seg_result);
   }
   }
   return true;
   return true;
 }
 }
@@ -115,7 +125,7 @@ bool SegPostprocess::Run(const std::vector<DataBlob>& outputs,
   int batch_size = shape_infos.size();
   int batch_size = shape_infos.size();
   results->resize(batch_size);
   results->resize(batch_size);
 
 
-  // tricks for PaddleX, which segmentation model has two outputs
+  // tricks for PaddleX, of which segmentation model has two outputs
   int index = 0;
   int index = 0;
   if (outputs.size() == 2) {
   if (outputs.size() == 2) {
     index = 1;
     index = 1;
@@ -126,10 +136,11 @@ bool SegPostprocess::Run(const std::vector<DataBlob>& outputs,
     return RunV2(outputs[index], shape_infos, results, thread_num);
     return RunV2(outputs[index], shape_infos, results, thread_num);
   }
   }
 
 
-  int score_map_size = std::accumulate(score_map_shape.begin() + 1,
-                    score_map_shape.end(), 1, std::multiplies<int>());
+  int score_map_size =
+      std::accumulate(score_map_shape.begin() + 1, score_map_shape.end(), 1,
+                      std::multiplies<int>());
   const float* score_map_data =
   const float* score_map_data =
-        reinterpret_cast<const float*>(outputs[index].data.data());
+      reinterpret_cast<const float*>(outputs[index].data.data());
   int num_map_pixels = score_map_shape[2] * score_map_shape[3];
   int num_map_pixels = score_map_shape[2] * score_map_shape[3];
 
 
   for (int i = 0; i < batch_size; ++i) {
   for (int i = 0; i < batch_size; ++i) {
@@ -137,8 +148,8 @@ bool SegPostprocess::Run(const std::vector<DataBlob>& outputs,
     (*results)[i].seg_result = new SegResult();
     (*results)[i].seg_result = new SegResult();
     const float* current_start_ptr = score_map_data + i * score_map_size;
     const float* current_start_ptr = score_map_data + i * score_map_size;
     cv::Mat ori_score_mat(score_map_shape[1],
     cv::Mat ori_score_mat(score_map_shape[1],
-            score_map_shape[2] * score_map_shape[3],
-            CV_32FC1, const_cast<float*>(current_start_ptr));
+                          score_map_shape[2] * score_map_shape[3], CV_32FC1,
+                          const_cast<float*>(current_start_ptr));
     ori_score_mat = ori_score_mat.t();
     ori_score_mat = ori_score_mat.t();
     cv::Mat score_mat(score_map_shape[2], score_map_shape[3], CV_32FC1);
     cv::Mat score_mat(score_map_shape[2], score_map_shape[3], CV_32FC1);
     cv::Mat label_mat(score_map_shape[2], score_map_shape[3], CV_8UC1);
     cv::Mat label_mat(score_map_shape[2], score_map_shape[3], CV_8UC1);
@@ -149,8 +160,8 @@ bool SegPostprocess::Run(const std::vector<DataBlob>& outputs,
       score_mat.at<float>(j) = max_value;
       score_mat.at<float>(j) = max_value;
       label_mat.at<uchar>(j) = max_id.x;
       label_mat.at<uchar>(j) = max_id.x;
     }
     }
-    RestoreSegMap(shape_infos[i], &label_mat,
-                &score_mat, (*results)[i].seg_result);
+    RestoreSegMap(shape_infos[i], &label_mat, &score_mat,
+                  (*results)[i].seg_result);
   }
   }
   return true;
   return true;
 }
 }

+ 24 - 24
paddlex/cv/models/segmenter.py

@@ -105,7 +105,7 @@ class BaseSegmenter(BaseModel):
         if mode == 'test':
         if mode == 'test':
             origin_shape = inputs[1]
             origin_shape = inputs[1]
             if self.status == 'Infer':
             if self.status == 'Infer':
-                score_map, label_map = self._postprocess(
+                label_map, score_map = self._postprocess(
                     net_out, origin_shape, transforms=inputs[2])
                     net_out, origin_shape, transforms=inputs[2])
             else:
             else:
                 logit = self._postprocess(
                 logit = self._postprocess(
@@ -582,8 +582,8 @@ class BaseSegmenter(BaseModel):
             batch_origin_shape, transforms)
             batch_origin_shape, transforms)
         if isinstance(batch_pred, (tuple, list)) and self.status == 'Infer':
         if isinstance(batch_pred, (tuple, list)) and self.status == 'Infer':
             return self._infer_postprocess(
             return self._infer_postprocess(
-                batch_score_map=batch_pred[0],
-                batch_label_map=batch_pred[1],
+                batch_label_map=batch_pred[0],
+                batch_score_map=batch_pred[1],
                 batch_restore_list=batch_restore_list)
                 batch_restore_list=batch_restore_list)
         results = []
         results = []
         for pred, restore_list in zip(batch_pred, batch_restore_list):
         for pred, restore_list in zip(batch_pred, batch_restore_list):
@@ -602,50 +602,50 @@ class BaseSegmenter(BaseModel):
         batch_pred = paddle.concat(results, axis=0)
         batch_pred = paddle.concat(results, axis=0)
         return batch_pred
         return batch_pred
 
 
-    def _infer_postprocess(self, batch_score_map, batch_label_map,
+    def _infer_postprocess(self, batch_label_map, batch_score_map,
                            batch_restore_list):
                            batch_restore_list):
-        score_maps = []
         label_maps = []
         label_maps = []
-        for score_map, label_map, restore_list in zip(
-                batch_score_map, batch_label_map, batch_restore_list):
-            if not isinstance(score_map, np.ndarray):
-                score_map = paddle.unsqueeze(score_map, axis=0)
+        score_maps = []
+        for label_map, score_map, restore_list in zip(
+                batch_label_map, batch_score_map, batch_restore_list):
+            if not isinstance(label_map, np.ndarray):
                 label_map = paddle.unsqueeze(label_map, axis=0)
                 label_map = paddle.unsqueeze(label_map, axis=0)
+                score_map = paddle.unsqueeze(score_map, axis=0)
             for item in restore_list[::-1]:
             for item in restore_list[::-1]:
                 h, w = item[1][0], item[1][1]
                 h, w = item[1][0], item[1][1]
                 if item[0] == 'resize':
                 if item[0] == 'resize':
-                    if isinstance(score_map, np.ndarray):
-                        score_map = cv2.resize(
-                            score_map, (h, w), interpolation=cv2.INTER_LINEAR)
+                    if isinstance(label_map, np.ndarray):
                         label_map = cv2.resize(
                         label_map = cv2.resize(
                             label_map, (h, w), interpolation=cv2.INTER_NEAREST)
                             label_map, (h, w), interpolation=cv2.INTER_NEAREST)
+                        score_map = cv2.resize(
+                            score_map, (h, w), interpolation=cv2.INTER_LINEAR)
                     else:
                     else:
-                        score_map = F.interpolate(
-                            score_map, (h, w),
-                            mode='bilinear',
-                            data_format='NHWC')
                         label_map = F.interpolate(
                         label_map = F.interpolate(
                             label_map, (h, w),
                             label_map, (h, w),
                             mode='nearest',
                             mode='nearest',
                             data_format='NHWC')
                             data_format='NHWC')
+                        score_map = F.interpolate(
+                            score_map, (h, w),
+                            mode='bilinear',
+                            data_format='NHWC')
                 elif item[0] == 'padding':
                 elif item[0] == 'padding':
                     x, y = item[2]
                     x, y = item[2]
-                    if isinstance(score_map, np.ndarray):
-                        score_map = score_map[..., y:y + h, x:x + w]
+                    if isinstance(label_map, np.ndarray):
                         label_map = label_map[..., y:y + h, x:x + w]
                         label_map = label_map[..., y:y + h, x:x + w]
+                        score_map = score_map[..., y:y + h, x:x + w]
                     else:
                     else:
-                        score_map = score_map[:, :, y:y + h, x:x + w]
                         label_map = label_map[:, :, y:y + h, x:x + w]
                         label_map = label_map[:, :, y:y + h, x:x + w]
+                        score_map = score_map[:, :, y:y + h, x:x + w]
                 else:
                 else:
                     pass
                     pass
-            score_maps.append(score_map)
             label_maps.append(label_map)
             label_maps.append(label_map)
-        if isinstance(score_maps[0], np.ndarray):
-            return np.stack(score_maps, axis=0), np.stack(label_maps, axis=0)
+            score_maps.append(score_map)
+        if isinstance(label_maps[0], np.ndarray):
+            return np.stack(label_maps, axis=0), np.stack(score_maps, axis=0)
         else:
         else:
             return paddle.concat(
             return paddle.concat(
-                score_maps, axis=0), paddle.concat(
-                    label_maps, axis=0)
+                label_maps, axis=0), paddle.concat(
+                    score_maps, axis=0)
 
 
 
 
 class UNet(BaseSegmenter):
 class UNet(BaseSegmenter):

+ 3 - 4
paddlex/cv/models/utils/infer_nets.py

@@ -24,11 +24,10 @@ class PostProcessor(paddle.nn.Layer):
         if self.model_type == 'classifier':
         if self.model_type == 'classifier':
             outputs = paddle.nn.functional.softmax(net_outputs, axis=1)
             outputs = paddle.nn.functional.softmax(net_outputs, axis=1)
         else:
         else:
-            # score_map, label_map
+            # label_map, score_map
             logit = net_outputs[0]
             logit = net_outputs[0]
-            outputs = paddle.transpose(paddle.nn.functional.softmax(logit, axis=1), perm=[0, 2, 3, 1]), \
-                      paddle.transpose(paddle.argmax(logit, axis=1, keepdim=True, dtype='int32'),
-                                       perm=[0, 2, 3, 1])
+            outputs = paddle.transpose(paddle.argmax(logit, axis=1, keepdim=True, dtype='int32'), perm=[0, 2, 3, 1]), \
+                      paddle.transpose(paddle.nn.functional.softmax(logit, axis=1), perm=[0, 2, 3, 1])
 
 
         return outputs
         return outputs
 
 

+ 2 - 2
paddlex/deploy.py

@@ -152,12 +152,12 @@ class Predictor(object):
             if len(preds) == 1:
             if len(preds) == 1:
                 preds = preds[0]
                 preds = preds[0]
         elif self._model.model_type == 'segmenter':
         elif self._model.model_type == 'segmenter':
-            score_map, label_map = self._model._postprocess(
+            label_map, score_map = self._model._postprocess(
                 net_outputs,
                 net_outputs,
                 batch_origin_shape=ori_shape,
                 batch_origin_shape=ori_shape,
                 transforms=transforms.transforms)
                 transforms=transforms.transforms)
-            score_map = np.squeeze(score_map)
             label_map = np.squeeze(label_map)
             label_map = np.squeeze(label_map)
+            score_map = np.squeeze(score_map)
             if score_map.ndim == 3:
             if score_map.ndim == 3:
                 preds = {'label_map': label_map, 'score_map': score_map}
                 preds = {'label_map': label_map, 'score_map': score_map}
             else:
             else: