diff --git a/configs/centernet/_base_/centernet_reader.yml b/configs/centernet/_base_/centernet_reader.yml index 1f18dca49d1e39c61b9bbc7b5be8bfac7bce5ca4..81af4ab840502da6e738ac667dd0883041ba8992 100644 --- a/configs/centernet/_base_/centernet_reader.yml +++ b/configs/centernet/_base_/centernet_reader.yml @@ -30,6 +30,6 @@ TestReader: sample_transforms: - Decode: {} - WarpAffine: {keep_res: True, input_h: 512, input_w: 512} - - NormalizeImage: {mean: [0.40789655, 0.44719303, 0.47026116], std: [0.2886383 , 0.27408165, 0.27809834]} + - NormalizeImage: {mean: [0.40789655, 0.44719303, 0.47026116], std: [0.2886383 , 0.27408165, 0.27809834], is_scale: True} - Permute: {} batch_size: 1 diff --git a/deploy/cpp/include/preprocess_op.h b/deploy/cpp/include/preprocess_op.h index 33d7300b8fd84287cca91e86214084acec781030..2d24799a332293a8ef14a32d6d09f6daaa116425 100644 --- a/deploy/cpp/include/preprocess_op.h +++ b/deploy/cpp/include/preprocess_op.h @@ -74,7 +74,7 @@ class NormalizeImage : public PreprocessOp { // CHW or HWC std::vector mean_; std::vector scale_; - bool is_scale_; + bool is_scale_ = true; }; class Permute : public PreprocessOp { @@ -143,6 +143,24 @@ class TopDownEvalAffine : public PreprocessOp { std::vector trainsize_; }; +class WarpAffine : public PreprocessOp { + public: + virtual void Init(const YAML::Node& item) { + input_h_ = item["input_h"].as(); + input_w_ = item["input_w"].as(); + keep_res_ = item["keep_res"].as(); + } + + virtual void Run(cv::Mat* im, ImageBlob* data); + + private: + int input_h_; + int input_w_; + int interp_ = 1; + bool keep_res_ = true; + int pad_ = 31; +}; + void CropImg(cv::Mat& img, cv::Mat& crop_img, std::vector& area, @@ -183,6 +201,8 @@ class Preprocessor { return std::make_shared(); } else if (name == "TopDownEvalAffine") { return std::make_shared(); + } else if (name == "WarpAffine") { + return std::make_shared(); } std::cerr << "can not find function of OP: " << name << " and return: nullptr" << std::endl; diff --git a/deploy/cpp/src/preprocess_op.cc b/deploy/cpp/src/preprocess_op.cc index d4a1fb4191b449267581c71e94b5ff959ac886c3..98c700f6219ca4201d87902d2b337d5adc4d0d5c 100644 --- a/deploy/cpp/src/preprocess_op.cc +++ b/deploy/cpp/src/preprocess_op.cc @@ -177,11 +177,64 @@ void TopDownEvalAffine::Run(cv::Mat* im, ImageBlob* data) { }; } +void GetAffineTrans(const cv::Point2f center, + const cv::Point2f input_size, + const cv::Point2f output_size, + cv::Mat* trans) { + cv::Point2f srcTri[3]; + cv::Point2f dstTri[3]; + float src_w = input_size.x; + float dst_w = output_size.x; + float dst_h = output_size.y; + + cv::Point2f src_dir(0, -0.5 * src_w); + cv::Point2f dst_dir(0, -0.5 * dst_w); + + srcTri[0] = center; + srcTri[1] = center + src_dir; + cv::Point2f src_d = srcTri[0] - srcTri[1]; + srcTri[2] = srcTri[1] + cv::Point2f(-src_d.y, src_d.x); + + dstTri[0] = cv::Point2f(dst_w * 0.5, dst_h * 0.5); + dstTri[1] = cv::Point2f(dst_w * 0.5, dst_h * 0.5) + dst_dir; + cv::Point2f dst_d = dstTri[0] - dstTri[1]; + dstTri[2] = dstTri[1] + cv::Point2f(-dst_d.y, dst_d.x); + + *trans = cv::getAffineTransform(srcTri, dstTri); +} + +void WarpAffine::Run(cv::Mat* im, ImageBlob* data) { + cv::cvtColor(*im, *im, cv::COLOR_RGB2BGR); + cv::Mat trans(2, 3, CV_32FC1); + cv::Point2f center; + cv::Point2f input_size; + int h = im->rows; + int w = im->cols; + if (keep_res_) { + input_h_ = (h | pad_) + 1; + input_w_ = (w + pad_) + 1; + input_size = cv::Point2f(input_w_, input_h_); + center = cv::Point2f(w / 2, h / 2); + } else { + float s = std::max(h, w) * 1.0; + input_size = cv::Point2f(s, s); + center = cv::Point2f(w / 2., h / 2.); + } + cv::Point2f output_size(input_w_, input_h_); + + GetAffineTrans(center, input_size, output_size, &trans); + cv::warpAffine(*im, *im, trans, cv::Size(input_w_, input_h_)); + data->in_net_shape_ = { + static_cast(input_h_), static_cast(input_w_), + }; +} + // Preprocessor op running order const std::vector Preprocessor::RUN_ORDER = {"InitInfo", "TopDownEvalAffine", "Resize", "LetterBoxResize", + "WarpAffine", "NormalizeImage", "PadStride", "Permute"}; diff --git a/ppdet/modeling/post_process.py b/ppdet/modeling/post_process.py index e74095505222142d47c17a0e665d358561558173..c64befa8176cd7fb9fb820a0aa3d82adbf7e4396 100644 --- a/ppdet/modeling/post_process.py +++ b/ppdet/modeling/post_process.py @@ -524,7 +524,7 @@ class CenterNetPostProcess(TTFBox): x2 = xs + wh[:, 0:1] / 2 y2 = ys + wh[:, 1:2] / 2 - n, c, feat_h, feat_w = hm.shape[:] + n, c, feat_h, feat_w = paddle.shape(hm) padw = (feat_w * self.down_ratio - im_shape[0, 1]) / 2 padh = (feat_h * self.down_ratio - im_shape[0, 0]) / 2 x1 = x1 * self.down_ratio