| @@ -43,8 +43,8 @@ Status SoftDvppDecodeRandomCropResizeJpegOp::GetCropInfo(const std::shared_ptr<T | |||||
| RETURN_IF_NOT_OK(GetCropBox(img_height, img_width, &x, &y, &crop_heigh, &crop_widht)); | RETURN_IF_NOT_OK(GetCropBox(img_height, img_width, &x, &y, &crop_heigh, &crop_widht)); | ||||
| crop_info->left = x; | crop_info->left = x; | ||||
| crop_info->up = y; | crop_info->up = y; | ||||
| crop_info->right = crop_info->left + crop_widht; | |||||
| crop_info->down = crop_info->up + crop_heigh; | |||||
| crop_info->right = crop_info->left + crop_widht - 1; | |||||
| crop_info->down = crop_info->up + crop_heigh - 1; | |||||
| return Status::OK(); | return Status::OK(); | ||||
| } | } | ||||
| @@ -15,6 +15,7 @@ | |||||
| */ | */ | ||||
| #include "minddata/dataset/kernels/image/soft_dvpp/soft_dvpp_decode_resize_jpeg_op.h" | #include "minddata/dataset/kernels/image/soft_dvpp/soft_dvpp_decode_resize_jpeg_op.h" | ||||
| #include <string> | #include <string> | ||||
| #include <vector> | |||||
| #include "./utils/external_soft_dp.h" | #include "./utils/external_soft_dp.h" | ||||
| #include "opencv2/opencv.hpp" | #include "opencv2/opencv.hpp" | ||||
| @@ -35,14 +36,32 @@ Status SoftDvppDecodeResizeJpegOp::Compute(const std::shared_ptr<Tensor> &input, | |||||
| SoftDpProcsessInfo info; | SoftDpProcsessInfo info; | ||||
| info.input_buffer = static_cast<uint8_t *>(buffer); | info.input_buffer = static_cast<uint8_t *>(buffer); | ||||
| info.input_buffer_size = input->SizeInBytes(); | info.input_buffer_size = input->SizeInBytes(); | ||||
| info.output_width = target_width_; | |||||
| info.output_height = target_height_; | |||||
| int input_w = 0; | |||||
| int input_h = 0; | |||||
| RETURN_IF_NOT_OK(GetJpegImageInfo(input, &input_w, &input_h)); | |||||
| SoftDpCropInfo crop_info{0, 0, 0, 0}; | SoftDpCropInfo crop_info{0, 0, 0, 0}; | ||||
| cv::Mat out_rgb_img(target_height_, target_width_, CV_8UC3); | |||||
| if (target_width_ == 0) { | |||||
| if (input_h < input_w) { | |||||
| CHECK_FAIL_RETURN_UNEXPECTED(input_h != 0, "The input height is 0"); | |||||
| info.output_height = target_height_; | |||||
| info.output_width = static_cast<int>(std::lround(static_cast<float>(input_w) / input_h * info.output_height)); | |||||
| } else { | |||||
| CHECK_FAIL_RETURN_UNEXPECTED(input_w != 0, "The input width is 0"); | |||||
| info.output_width = target_height_; | |||||
| info.output_height = static_cast<int>(std::lround(static_cast<float>(input_h) / input_w * info.output_width)); | |||||
| } | |||||
| } else { | |||||
| info.output_height = target_height_; | |||||
| info.output_width = target_width_; | |||||
| } | |||||
| cv::Mat out_rgb_img(info.output_height, info.output_width, CV_8UC3); | |||||
| info.output_buffer = out_rgb_img.data; | info.output_buffer = out_rgb_img.data; | ||||
| info.output_buffer_size = target_width_ * target_height_ * 3; | |||||
| info.output_buffer_size = info.output_height * info.output_width * 3; | |||||
| info.is_v_before_u = true; | info.is_v_before_u = true; | ||||
| int ret = DecodeAndResizeJpeg(&info); | int ret = DecodeAndResizeJpeg(&info); | ||||
| std::string error_info("Soft dvpp DecodeAndResizeJpeg failed with return code: "); | std::string error_info("Soft dvpp DecodeAndResizeJpeg failed with return code: "); | ||||
| @@ -56,5 +75,16 @@ Status SoftDvppDecodeResizeJpegOp::Compute(const std::shared_ptr<Tensor> &input, | |||||
| } | } | ||||
| return Status::OK(); | return Status::OK(); | ||||
| } | } | ||||
| Status SoftDvppDecodeResizeJpegOp::OutputShape(const std::vector<TensorShape> &inputs, | |||||
| std::vector<TensorShape> &outputs) { | |||||
| RETURN_IF_NOT_OK(TensorOp::OutputShape(inputs, outputs)); | |||||
| outputs.clear(); | |||||
| TensorShape out({-1, -1, 3}); // we don't know what is output image size, but we know it should be 3 channels | |||||
| if (inputs[0].Rank() == 1) outputs.emplace_back(out); | |||||
| if (!outputs.empty()) return Status::OK(); | |||||
| return Status(StatusCode::kUnexpectedError, "Input has a wrong shape"); | |||||
| } | |||||
| } // namespace dataset | } // namespace dataset | ||||
| } // namespace mindspore | } // namespace mindspore | ||||
| @@ -18,6 +18,7 @@ | |||||
| #include <memory> | #include <memory> | ||||
| #include <string> | #include <string> | ||||
| #include <vector> | |||||
| #include "minddata/dataset/core/tensor.h" | #include "minddata/dataset/core/tensor.h" | ||||
| #include "minddata/dataset/kernels/tensor_op.h" | #include "minddata/dataset/kernels/tensor_op.h" | ||||
| @@ -34,6 +35,7 @@ class SoftDvppDecodeResizeJpegOp : public TensorOp { | |||||
| ~SoftDvppDecodeResizeJpegOp() = default; | ~SoftDvppDecodeResizeJpegOp() = default; | ||||
| Status Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) override; | Status Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) override; | ||||
| Status OutputShape(const std::vector<TensorShape> &inputs, std::vector<TensorShape> &outputs) override; | |||||
| std::string Name() const override { return kSoftDvppDecodeReiszeJpegOp; } | std::string Name() const override { return kSoftDvppDecodeReiszeJpegOp; } | ||||
| @@ -943,7 +943,7 @@ class SoftDvppDecodeResizeJpeg(cde.SoftDvppDecodeResizeJpegOp): | |||||
| @check_resize | @check_resize | ||||
| def __init__(self, size): | def __init__(self, size): | ||||
| if isinstance(size, int): | if isinstance(size, int): | ||||
| size = (size, size) | |||||
| size = (size, 0) | |||||
| self.size = size | self.size = size | ||||
| super().__init__(*size) | super().__init__(*size) | ||||
| @@ -84,7 +84,38 @@ def test_soft_dvpp_decode_random_crop_resize_jpeg(plot=False): | |||||
| visualize_image(image1, image2, mse) | visualize_image(image1, image2, mse) | ||||
| num_iter += 1 | num_iter += 1 | ||||
| def test_soft_dvpp_decode_resize_jpeg_supplement(plot=False): | |||||
| """ | |||||
| Test SoftDvppDecodeResizeJpeg op | |||||
| """ | |||||
| logger.info("test_random_decode_resize_op") | |||||
| # First dataset | |||||
| data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False) | |||||
| decode_op = vision.Decode() | |||||
| resize_op = vision.Resize(256) | |||||
| data1 = data1.map(input_columns=["image"], operations=[decode_op, resize_op]) | |||||
| # Second dataset | |||||
| data2 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False) | |||||
| soft_dvpp_decode_resize_op = vision.SoftDvppDecodeResizeJpeg(256) | |||||
| data2 = data2.map(input_columns=["image"], operations=soft_dvpp_decode_resize_op) | |||||
| num_iter = 0 | |||||
| for item1, item2 in zip(data1.create_dict_iterator(), data2.create_dict_iterator()): | |||||
| if num_iter > 0: | |||||
| break | |||||
| image1 = item1["image"] | |||||
| image2 = item2["image"] | |||||
| mse = diff_mse(image1, image2) | |||||
| assert mse <= 0.02 | |||||
| logger.info("random_crop_decode_resize_op_{}, mse: {}".format(num_iter + 1, mse)) | |||||
| if plot: | |||||
| visualize_image(image1, image2, mse) | |||||
| num_iter += 1 | |||||
| if __name__ == "__main__": | if __name__ == "__main__": | ||||
| test_soft_dvpp_decode_resize_jpeg(plot=True) | test_soft_dvpp_decode_resize_jpeg(plot=True) | ||||
| test_soft_dvpp_decode_random_crop_resize_jpeg(plot=True) | test_soft_dvpp_decode_random_crop_resize_jpeg(plot=True) | ||||
| test_soft_dvpp_decode_resize_jpeg_supplement(plot=True) | |||||