• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2020-2021 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 
17 #include <algorithm>
18 #include "minddata/dataset/kernels/ir/vision/ascend_vision_ir.h"
19 
20 #include "minddata/dataset/kernels/image/dvpp/dvpp_crop_jpeg_op.h"
21 #include "minddata/dataset/kernels/image/dvpp/dvpp_decode_resize_jpeg_op.h"
22 #include "minddata/dataset/kernels/image/dvpp/dvpp_decode_resize_crop_jpeg_op.h"
23 #include "minddata/dataset/kernels/image/dvpp/dvpp_decode_jpeg_op.h"
24 #include "minddata/dataset/kernels/image/dvpp/dvpp_decode_png_op.h"
25 #include "minddata/dataset/kernels/image/dvpp/dvpp_normalize_op.h"
26 #include "minddata/dataset/kernels/image/dvpp/dvpp_resize_jpeg_op.h"
27 
28 namespace mindspore {
29 namespace dataset {
30 
31 // Transform operations for computer vision
32 namespace vision {
33 /* ####################################### Derived TensorOperation classes ################################# */
34 
35 // DvppCropOperation
DvppCropJpegOperation(const std::vector<uint32_t> & crop)36 DvppCropJpegOperation::DvppCropJpegOperation(const std::vector<uint32_t> &crop) : crop_(crop) {}
37 
ValidateParams()38 Status DvppCropJpegOperation::ValidateParams() {
39   // size
40   if (crop_.empty() || crop_.size() > 2) {
41     std::string err_msg =
42       "DvppCropJpeg: Crop resolution must be a vector of one or two elements, got: " + std::to_string(crop_.size());
43     MS_LOG(ERROR) << err_msg;
44     RETURN_STATUS_SYNTAX_ERROR(err_msg);
45   }
46   if (*min_element(crop_.begin(), crop_.end()) < 32 || *max_element(crop_.begin(), crop_.end()) > 2048) {
47     std::string err_msg = "Dvpp module supports crop image with resolution in range [32, 2048], got crop Parameters: ";
48     if (crop_.size() == 2) {
49       MS_LOG(ERROR) << err_msg << "[" << crop_[0] << ", " << crop_[1] << "]";
50     } else {
51       MS_LOG(ERROR) << err_msg << "[" << crop_[0] << ", " << crop_[0] << "]";
52     }
53     RETURN_STATUS_SYNTAX_ERROR(err_msg);
54   }
55   return Status::OK();
56 }
57 
Build()58 std::shared_ptr<TensorOp> DvppCropJpegOperation::Build() {
59   // If size is a single value, the smaller edge of the image will be
60   // resized to this value with the same image aspect ratio.
61   uint32_t cropHeight, cropWidth;
62   // User specified the width value.
63   if (crop_.size() == 1) {
64     cropHeight = crop_[0];
65     cropWidth = crop_[0];
66   } else {
67     cropHeight = crop_[0];
68     cropWidth = crop_[1];
69   }
70   std::shared_ptr<DvppCropJpegOp> tensor_op = std::make_shared<DvppCropJpegOp>(cropHeight, cropWidth);
71   return tensor_op;
72 }
73 
to_json(nlohmann::json * out_json)74 Status DvppCropJpegOperation::to_json(nlohmann::json *out_json) {
75   nlohmann::json args;
76   args["size"] = crop_;
77   *out_json = args;
78   return Status::OK();
79 }
80 
from_json(nlohmann::json op_params,std::shared_ptr<TensorOperation> * operation)81 Status DvppCropJpegOperation::from_json(nlohmann::json op_params, std::shared_ptr<TensorOperation> *operation) {
82   CHECK_FAIL_RETURN_UNEXPECTED(op_params.find("size") != op_params.end(), "Fail to find size");
83   std::vector<uint32_t> resize = op_params["size"];
84   *operation = std::make_shared<vision::DvppCropJpegOperation>(resize);
85   return Status::OK();
86 }
87 
88 // DvppDecodeResizeOperation
DvppDecodeResizeOperation(const std::vector<uint32_t> & resize)89 DvppDecodeResizeOperation::DvppDecodeResizeOperation(const std::vector<uint32_t> &resize) : resize_(resize) {}
90 
ValidateParams()91 Status DvppDecodeResizeOperation::ValidateParams() {
92   // size
93   if (resize_.empty() || resize_.size() > 2) {
94     std::string err_msg = "DvppDecodeResizeJpeg: resize resolution must be a vector of one or two elements, got: " +
95                           std::to_string(resize_.size());
96     MS_LOG(ERROR) << err_msg;
97     RETURN_STATUS_SYNTAX_ERROR(err_msg);
98   }
99   if (*min_element(resize_.begin(), resize_.end()) < 32 || *max_element(resize_.begin(), resize_.end()) > 2048) {
100     std::string err_msg =
101       "Dvpp module supports resize image with resolution in range [32, 2048], got resize Parameters: ";
102     if (resize_.size() == 2) {
103       MS_LOG(ERROR) << err_msg << "[" << resize_[0] << ", " << resize_[1] << "]";
104     } else {
105       MS_LOG(ERROR) << err_msg << "[" << resize_[0] << ", " << resize_[0] << "]";
106     }
107     RETURN_STATUS_SYNTAX_ERROR(err_msg);
108   }
109   return Status::OK();
110 }
111 
Build()112 std::shared_ptr<TensorOp> DvppDecodeResizeOperation::Build() {
113   // If size is a single value, the smaller edge of the image will be
114   // resized to this value with the same image aspect ratio.
115   uint32_t resizeHeight, resizeWidth;
116   // User specified the width value.
117   if (resize_.size() == 1) {
118     resizeHeight = resize_[0];
119     resizeWidth = 0;
120   } else {
121     resizeHeight = resize_[0];
122     resizeWidth = resize_[1];
123   }
124   std::shared_ptr<DvppDecodeResizeJpegOp> tensor_op =
125     std::make_shared<DvppDecodeResizeJpegOp>(resizeHeight, resizeWidth);
126   return tensor_op;
127 }
128 
to_json(nlohmann::json * out_json)129 Status DvppDecodeResizeOperation::to_json(nlohmann::json *out_json) {
130   nlohmann::json args;
131   args["size"] = resize_;
132   *out_json = args;
133   return Status::OK();
134 }
135 
from_json(nlohmann::json op_params,std::shared_ptr<TensorOperation> * operation)136 Status DvppDecodeResizeOperation::from_json(nlohmann::json op_params, std::shared_ptr<TensorOperation> *operation) {
137   CHECK_FAIL_RETURN_UNEXPECTED(op_params.find("size") != op_params.end(), "Fail to find size");
138   std::vector<uint32_t> resize = op_params["size"];
139   *operation = std::make_shared<vision::DvppDecodeResizeOperation>(resize);
140   return Status::OK();
141 }
142 
143 // DvppDecodeResizeCropOperation
DvppDecodeResizeCropOperation(const std::vector<uint32_t> & crop,const std::vector<uint32_t> & resize)144 DvppDecodeResizeCropOperation::DvppDecodeResizeCropOperation(const std::vector<uint32_t> &crop,
145                                                              const std::vector<uint32_t> &resize)
146     : crop_(crop), resize_(resize) {}
147 
ValidateParams()148 Status DvppDecodeResizeCropOperation::ValidateParams() {
149   // size
150   if (crop_.empty() || crop_.size() > 2) {
151     std::string err_msg = "DvppDecodeResizeCropJpeg: crop resolution must be a vector of one or two elements, got: " +
152                           std::to_string(crop_.size());
153     MS_LOG(ERROR) << err_msg;
154     RETURN_STATUS_SYNTAX_ERROR(err_msg);
155   }
156   if (resize_.empty() || resize_.size() > 2) {
157     std::string err_msg = "DvppDecodeResizeCropJpeg: resize resolution must be a vector of one or two elements, got: " +
158                           std::to_string(resize_.size());
159     MS_LOG(ERROR) << err_msg;
160     RETURN_STATUS_SYNTAX_ERROR(err_msg);
161   }
162   if (*min_element(crop_.begin(), crop_.end()) < 32 || *max_element(crop_.begin(), crop_.end()) > 2048) {
163     std::string err_msg = "Dvpp module supports crop image with resolution in range [32, 2048], got Crop Parameters: ";
164     if (crop_.size() == 2) {
165       MS_LOG(ERROR) << err_msg << "[" << crop_[0] << ", " << crop_[1] << "]";
166     } else {
167       MS_LOG(ERROR) << err_msg << "[" << crop_[0] << ", " << crop_[0] << "]";
168     }
169     RETURN_STATUS_SYNTAX_ERROR(err_msg);
170   }
171   if (*min_element(resize_.begin(), resize_.end()) < 32 || *max_element(resize_.begin(), resize_.end()) > 2048) {
172     std::string err_msg =
173       "Dvpp module supports resize image with resolution in range [32, 2048], got Crop Parameters: ";
174     if (resize_.size() == 2) {
175       MS_LOG(ERROR) << err_msg << "[" << resize_[0] << ", " << resize_[1] << "]";
176     } else {
177       MS_LOG(ERROR) << err_msg << "[" << resize_[0] << "]";
178     }
179     RETURN_STATUS_SYNTAX_ERROR(err_msg);
180   }
181   if (crop_.size() < resize_.size()) {
182     if (crop_[0] > MIN(resize_[0], resize_[1])) {
183       std::string err_msg =
184         "Each value of crop parameter must be smaller than corresponding resize parameter, for example: x[0] <= "
185         "y[0],  and x[1] <= y[1], please verify your input parameters.";
186       MS_LOG(ERROR) << err_msg;
187       RETURN_STATUS_SYNTAX_ERROR(err_msg);
188     }
189   }
190   if (crop_.size() > resize_.size()) {
191     if (MAX(crop_[0], crop_[1]) > resize_[0]) {
192       std::string err_msg =
193         "Each value of crop parameter must be smaller than corresponding resize parameter, for example: x[0] <= "
194         "y[0],  and x[1] <= y[1], please verify your input parameters.";
195       MS_LOG(ERROR) << err_msg;
196       RETURN_STATUS_SYNTAX_ERROR(err_msg);
197     }
198   }
199   if (crop_.size() == resize_.size()) {
200     for (int32_t i = 0; i < crop_.size(); ++i) {
201       if (crop_[i] > resize_[i]) {
202         std::string err_msg =
203           "Each value of crop parameter must be smaller than corresponding resize parameter, for example: x[0] <= "
204           "y[0],  and x[1] <= y[1], please verify your input parameters.";
205         MS_LOG(ERROR) << err_msg;
206         RETURN_STATUS_SYNTAX_ERROR(err_msg);
207       }
208     }
209   }
210   return Status::OK();
211 }
212 
Build()213 std::shared_ptr<TensorOp> DvppDecodeResizeCropOperation::Build() {
214   // If size is a single value, the smaller edge of the image will be
215   // resized to this value with the same image aspect ratio.
216   uint32_t cropHeight, cropWidth, resizeHeight, resizeWidth;
217   if (crop_.size() == 1) {
218     cropHeight = crop_[0];
219     cropWidth = crop_[0];
220   } else {
221     cropHeight = crop_[0];
222     cropWidth = crop_[1];
223   }
224   // User specified the width value.
225   if (resize_.size() == 1) {
226     resizeHeight = resize_[0];
227     resizeWidth = 0;
228   } else {
229     resizeHeight = resize_[0];
230     resizeWidth = resize_[1];
231   }
232   std::shared_ptr<DvppDecodeResizeCropJpegOp> tensor_op =
233     std::make_shared<DvppDecodeResizeCropJpegOp>(cropHeight, cropWidth, resizeHeight, resizeWidth);
234   return tensor_op;
235 }
236 
to_json(nlohmann::json * out_json)237 Status DvppDecodeResizeCropOperation::to_json(nlohmann::json *out_json) {
238   nlohmann::json args;
239   args["crop_size"] = crop_;
240   args["resize_size"] = resize_;
241   *out_json = args;
242   return Status::OK();
243 }
244 
from_json(nlohmann::json op_params,std::shared_ptr<TensorOperation> * operation)245 Status DvppDecodeResizeCropOperation::from_json(nlohmann::json op_params, std::shared_ptr<TensorOperation> *operation) {
246   CHECK_FAIL_RETURN_UNEXPECTED(op_params.find("crop_size") != op_params.end(), "Fail to find crop_size");
247   CHECK_FAIL_RETURN_UNEXPECTED(op_params.find("resize_size") != op_params.end(), "Fail to find resize_size");
248   std::vector<uint32_t> crop = op_params["crop_size"];
249   std::vector<uint32_t> resize = op_params["resize_size"];
250   *operation = std::make_shared<vision::DvppDecodeResizeCropOperation>(crop, resize);
251   return Status::OK();
252 }
253 
254 // DvppDecodeJPEG
ValidateParams()255 Status DvppDecodeJpegOperation::ValidateParams() { return Status::OK(); }
256 
Build()257 std::shared_ptr<TensorOp> DvppDecodeJpegOperation::Build() { return std::make_shared<DvppDecodeJpegOp>(); }
258 
259 // DvppDecodePNG
ValidateParams()260 Status DvppDecodePngOperation::ValidateParams() { return Status::OK(); }
261 
Build()262 std::shared_ptr<TensorOp> DvppDecodePngOperation::Build() { return std::make_shared<DvppDecodePngOp>(); }
263 
264 // DvppNormalize
DvppNormalizeOperation(const std::vector<float> & mean,const std::vector<float> & std)265 DvppNormalizeOperation::DvppNormalizeOperation(const std::vector<float> &mean, const std::vector<float> &std)
266     : mean_(mean), std_(std) {}
267 
ValidateParams()268 Status DvppNormalizeOperation::ValidateParams() {
269   if (mean_.size() != 3) {
270     std::string err_msg = "DvppNormalization:: mean expecting size 3, got size: " + std::to_string(mean_.size());
271     MS_LOG(ERROR) << err_msg;
272     RETURN_STATUS_SYNTAX_ERROR(err_msg);
273   }
274   if (std_.size() != 3) {
275     std::string err_msg = "DvppNormalization: std expecting size 3, got size: " + std::to_string(std_.size());
276     MS_LOG(ERROR) << err_msg;
277     RETURN_STATUS_SYNTAX_ERROR(err_msg);
278   }
279   if (*min_element(mean_.begin(), mean_.end()) < 0 || *max_element(mean_.begin(), mean_.end()) > 256) {
280     std::string err_msg =
281       "Normalization can take parameters in range [0, 256] according to math theory of mean and sigma, got mean "
282       "vector" +
283       std::to_string(std_.size());
284     MS_LOG(ERROR) << err_msg;
285     RETURN_STATUS_SYNTAX_ERROR(err_msg);
286   }
287   if (*min_element(std_.begin(), std_.end()) < 0 || *max_element(std_.begin(), std_.end()) > 256) {
288     std::string err_msg =
289       "Normalization can take parameters in range [0, 256] according to math theory of mean and sigma, got mean "
290       "vector" +
291       std::to_string(std_.size());
292     MS_LOG(ERROR) << err_msg;
293     RETURN_STATUS_SYNTAX_ERROR(err_msg);
294   }
295   return Status::OK();
296 }
297 
Build()298 std::shared_ptr<TensorOp> DvppNormalizeOperation::Build() {
299   std::shared_ptr<DvppNormalizeOp> tensor_op = std::make_shared<DvppNormalizeOp>(mean_, std_);
300   return tensor_op;
301 }
302 
to_json(nlohmann::json * out_json)303 Status DvppNormalizeOperation::to_json(nlohmann::json *out_json) {
304   nlohmann::json args;
305   std::vector<uint32_t> enlarge_mean_;
306   std::vector<uint32_t> enlarge_std_;
307   std::transform(mean_.begin(), mean_.end(), std::back_inserter(enlarge_mean_),
308                  [](float i) -> uint32_t { return static_cast<uint32_t>(10000 * i); });
309   std::transform(std_.begin(), std_.end(), std::back_inserter(enlarge_std_),
310                  [](float j) -> uint32_t { return static_cast<uint32_t>(10000 * j); });
311   args["mean"] = enlarge_mean_;
312   args["std"] = enlarge_std_;
313   *out_json = args;
314   return Status::OK();
315 }
316 
from_json(nlohmann::json op_params,std::shared_ptr<TensorOperation> * operation)317 Status DvppNormalizeOperation::from_json(nlohmann::json op_params, std::shared_ptr<TensorOperation> *operation) {
318   CHECK_FAIL_RETURN_UNEXPECTED(op_params.find("mean") != op_params.end(), "Fail to find mean");
319   CHECK_FAIL_RETURN_UNEXPECTED(op_params.find("std") != op_params.end(), "Fail to find std");
320   std::vector<float> mean = op_params["mean"];
321   std::vector<float> std = op_params["std"];
322   *operation = std::make_shared<vision::DvppNormalizeOperation>(mean, std);
323   return Status::OK();
324 }
325 
326 // DvppResizeOperation
DvppResizeJpegOperation(const std::vector<uint32_t> & resize)327 DvppResizeJpegOperation::DvppResizeJpegOperation(const std::vector<uint32_t> &resize) : resize_(resize) {}
328 
ValidateParams()329 Status DvppResizeJpegOperation::ValidateParams() {
330   // size
331   if (resize_.empty() || resize_.size() > 2) {
332     std::string err_msg = "DvppResizeJpeg: resize resolution must be a vector of one or two elements, got: " +
333                           std::to_string(resize_.size());
334     MS_LOG(ERROR) << err_msg;
335     RETURN_STATUS_SYNTAX_ERROR(err_msg);
336   }
337   if (*min_element(resize_.begin(), resize_.end()) < 32 || *max_element(resize_.begin(), resize_.end()) > 2048) {
338     std::string err_msg =
339       "Dvpp module supports resize image with resolution in range [32, 2048], got resize Parameters: ";
340     if (resize_.size() == 2) {
341       MS_LOG(ERROR) << err_msg << "[" << resize_[0] << ", " << resize_[1] << "]";
342     } else {
343       MS_LOG(ERROR) << err_msg << "[" << resize_[0] << ", " << resize_[0] << "]";
344     }
345     RETURN_STATUS_SYNTAX_ERROR(err_msg);
346   }
347   return Status::OK();
348 }
349 
Build()350 std::shared_ptr<TensorOp> DvppResizeJpegOperation::Build() {
351   // If size is a single value, the smaller edge of the image will be
352   // resized to this value with the same image aspect ratio.
353   uint32_t resizeHeight, resizeWidth;
354   // User specified the width value.
355   if (resize_.size() == 1) {
356     resizeHeight = resize_[0];
357     resizeWidth = 0;
358   } else {
359     resizeHeight = resize_[0];
360     resizeWidth = resize_[1];
361   }
362   std::shared_ptr<DvppResizeJpegOp> tensor_op = std::make_shared<DvppResizeJpegOp>(resizeHeight, resizeWidth);
363   return tensor_op;
364 }
365 
to_json(nlohmann::json * out_json)366 Status DvppResizeJpegOperation::to_json(nlohmann::json *out_json) {
367   nlohmann::json args;
368   args["size"] = resize_;
369   *out_json = args;
370   return Status::OK();
371 }
372 
from_json(nlohmann::json op_params,std::shared_ptr<TensorOperation> * operation)373 Status DvppResizeJpegOperation::from_json(nlohmann::json op_params, std::shared_ptr<TensorOperation> *operation) {
374   CHECK_FAIL_RETURN_UNEXPECTED(op_params.find("size") != op_params.end(), "Fail to find size");
375   std::vector<uint32_t> resize = op_params["size"];
376   *operation = std::make_shared<vision::DvppResizeJpegOperation>(resize);
377   return Status::OK();
378 }
379 }  // namespace vision
380 }  // namespace dataset
381 }  // namespace mindspore
382