1 /**
2 * Copyright 2020-2023 Huawei Technologies Co., Ltd
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "minddata/dataset/kernels/image/normalize_op.h"
17
18 #include <random>
19 #include <utility>
20 #include <vector>
21
22 #include "minddata/dataset/kernels/data/data_utils.h"
23 #ifndef ENABLE_ANDROID
24 #include "minddata/dataset/kernels/image/image_utils.h"
25 #else
26 #include "minddata/dataset/kernels/image/lite_image_utils.h"
27 #endif
28 #include "minddata/dataset/util/status.h"
29
30 namespace mindspore {
31 namespace dataset {
NormalizeOp(std::vector<float> mean,std::vector<float> std,bool is_hwc)32 NormalizeOp::NormalizeOp(std::vector<float> mean, std::vector<float> std, bool is_hwc)
33 : mean_(std::move(mean)), std_(std::move(std)), is_hwc_(is_hwc) {}
34
Compute(const std::shared_ptr<Tensor> & input,std::shared_ptr<Tensor> * output)35 Status NormalizeOp::Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) {
36 IO_CHECK(input, output);
37 // Doing the Normalization
38 auto input_shape = input->shape();
39 dsize_t rank = input_shape.Rank();
40 if (rank < kMinImageRank) {
41 std::string err_msg = "Normalize: input tensor should have at least 2 dimensions, but got: " + std::to_string(rank);
42 RETURN_STATUS_UNEXPECTED(err_msg);
43 } else if (rank <= kDefaultImageRank) {
44 // [H, W] or [H, W, C]
45 #ifndef ENABLE_ANDROID
46 return Normalize(input, output, mean_, std_, is_hwc_);
47 #else
48 return Normalize(input, output, mean_, std_);
49 #endif
50 } else {
51 // reshape [..., H, W, C] to [N, H, W, C]
52 dsize_t num_batch = input->Size() / (input_shape[-3] * input_shape[-2] * input_shape[-1]);
53 TensorShape new_shape({num_batch, input_shape[-3], input_shape[-2], input_shape[-1]});
54 RETURN_IF_NOT_OK(input->Reshape(new_shape));
55
56 // split [N, H, W, C] to N [H, W, C], and normalize N [H, W, C]
57 std::vector<std::shared_ptr<Tensor>> input_vector_hwc, output_vector_hwc;
58 RETURN_IF_NOT_OK(BatchTensorToTensorVector(input, &input_vector_hwc));
59 for (const auto &input_hwc : input_vector_hwc) {
60 std::shared_ptr<Tensor> normalize;
61 #ifndef ENABLE_ANDROID
62 RETURN_IF_NOT_OK(Normalize(input_hwc, &normalize, mean_, std_, is_hwc_));
63 #else
64 RETURN_IF_NOT_OK(Normalize(input_hwc, &normalize, mean_, std_));
65 #endif
66 output_vector_hwc.push_back(normalize);
67 }
68 // integrate N [H, W, C] to [N, H, W, C], and reshape [..., H, W, C]
69 RETURN_IF_NOT_OK(TensorVectorToBatchTensor(output_vector_hwc, &(*output)));
70 RETURN_IF_NOT_OK((*output)->Reshape(input_shape));
71 return Status::OK();
72 }
73 }
74
Print(std::ostream & out) const75 void NormalizeOp::Print(std::ostream &out) const {
76 out << "NormalizeOp, mean: ";
77 for (const auto &m : mean_) {
78 out << m << ", ";
79 }
80 out << "}" << std::endl << "std: ";
81 for (const auto &s : std_) {
82 out << s << ", ";
83 }
84 out << "}" << std::endl << "is_hwc: " << is_hwc_;
85 out << "}" << std::endl;
86 }
87 } // namespace dataset
88 } // namespace mindspore
89