You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

vision.cc 57 kB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468
  1. /**
  2. * Copyright 2020 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/include/transforms.h"
  17. #include "minddata/dataset/include/vision.h"
  18. #include "minddata/dataset/kernels/image/image_utils.h"
  19. // Kernel image headers (in alphabetical order)
  20. #include "minddata/dataset/kernels/image/center_crop_op.h"
  21. #include "minddata/dataset/kernels/image/crop_op.h"
  22. #include "minddata/dataset/kernels/image/cutmix_batch_op.h"
  23. #include "minddata/dataset/kernels/image/cut_out_op.h"
  24. #include "minddata/dataset/kernels/image/decode_op.h"
  25. #include "minddata/dataset/kernels/image/hwc_to_chw_op.h"
  26. #include "minddata/dataset/kernels/image/mixup_batch_op.h"
  27. #include "minddata/dataset/kernels/image/normalize_op.h"
  28. #include "minddata/dataset/kernels/image/pad_op.h"
  29. #include "minddata/dataset/kernels/image/random_affine_op.h"
  30. #include "minddata/dataset/kernels/image/random_color_op.h"
  31. #include "minddata/dataset/kernels/image/random_color_adjust_op.h"
  32. #include "minddata/dataset/kernels/image/random_crop_and_resize_op.h"
  33. #include "minddata/dataset/kernels/image/random_crop_op.h"
  34. #include "minddata/dataset/kernels/image/random_crop_decode_resize_op.h"
  35. #include "minddata/dataset/kernels/image/random_horizontal_flip_op.h"
  36. #include "minddata/dataset/kernels/image/random_posterize_op.h"
  37. #include "minddata/dataset/kernels/image/random_rotation_op.h"
  38. #include "minddata/dataset/kernels/image/random_sharpness_op.h"
  39. #include "minddata/dataset/kernels/image/random_solarize_op.h"
  40. #include "minddata/dataset/kernels/image/random_vertical_flip_op.h"
  41. #include "minddata/dataset/kernels/image/rescale_op.h"
  42. #include "minddata/dataset/kernels/image/resize_op.h"
  43. #include "minddata/dataset/kernels/image/rgba_to_bgr_op.h"
  44. #include "minddata/dataset/kernels/image/rgba_to_rgb_op.h"
  45. #include "minddata/dataset/kernels/image/swap_red_blue_op.h"
  46. #include "minddata/dataset/kernels/image/uniform_aug_op.h"
  47. namespace mindspore {
  48. namespace dataset {
  49. namespace api {
  50. // Transform operations for computer vision.
  51. namespace vision {
  52. // FUNCTIONS TO CREATE VISION TRANSFORM OPERATIONS
  53. // (In alphabetical order)
  54. // Function to create CenterCropOperation.
  55. std::shared_ptr<CenterCropOperation> CenterCrop(std::vector<int32_t> size) {
  56. auto op = std::make_shared<CenterCropOperation>(size);
  57. // Input validation
  58. if (!op->ValidateParams()) {
  59. return nullptr;
  60. }
  61. return op;
  62. }
  63. // Function to create CropOperation.
  64. std::shared_ptr<CropOperation> Crop(std::vector<int32_t> coordinates, std::vector<int32_t> size) {
  65. auto op = std::make_shared<CropOperation>(coordinates, size);
  66. // Input validation
  67. if (!op->ValidateParams()) {
  68. return nullptr;
  69. }
  70. return op;
  71. }
  72. // Function to create CutMixBatchOperation.
  73. std::shared_ptr<CutMixBatchOperation> CutMixBatch(ImageBatchFormat image_batch_format, float alpha, float prob) {
  74. auto op = std::make_shared<CutMixBatchOperation>(image_batch_format, alpha, prob);
  75. // Input validation
  76. if (!op->ValidateParams()) {
  77. return nullptr;
  78. }
  79. return op;
  80. }
  81. // Function to create CutOutOp.
  82. std::shared_ptr<CutOutOperation> CutOut(int32_t length, int32_t num_patches) {
  83. auto op = std::make_shared<CutOutOperation>(length, num_patches);
  84. // Input validation
  85. if (!op->ValidateParams()) {
  86. return nullptr;
  87. }
  88. return op;
  89. }
  90. // Function to create DecodeOperation.
  91. std::shared_ptr<DecodeOperation> Decode(bool rgb) {
  92. auto op = std::make_shared<DecodeOperation>(rgb);
  93. // Input validation
  94. if (!op->ValidateParams()) {
  95. return nullptr;
  96. }
  97. return op;
  98. }
  99. // Function to create HwcToChwOperation.
  100. std::shared_ptr<HwcToChwOperation> HWC2CHW() {
  101. auto op = std::make_shared<HwcToChwOperation>();
  102. // Input validation
  103. if (!op->ValidateParams()) {
  104. return nullptr;
  105. }
  106. return op;
  107. }
  108. // Function to create MixUpBatchOperation.
  109. std::shared_ptr<MixUpBatchOperation> MixUpBatch(float alpha) {
  110. auto op = std::make_shared<MixUpBatchOperation>(alpha);
  111. // Input validation
  112. if (!op->ValidateParams()) {
  113. return nullptr;
  114. }
  115. return op;
  116. }
  117. // Function to create NormalizeOperation.
  118. std::shared_ptr<NormalizeOperation> Normalize(std::vector<float> mean, std::vector<float> std) {
  119. auto op = std::make_shared<NormalizeOperation>(mean, std);
  120. // Input validation
  121. if (!op->ValidateParams()) {
  122. return nullptr;
  123. }
  124. return op;
  125. }
  126. // Function to create PadOperation.
  127. std::shared_ptr<PadOperation> Pad(std::vector<int32_t> padding, std::vector<uint8_t> fill_value,
  128. BorderType padding_mode) {
  129. auto op = std::make_shared<PadOperation>(padding, fill_value, padding_mode);
  130. // Input validation
  131. if (!op->ValidateParams()) {
  132. return nullptr;
  133. }
  134. return op;
  135. }
  136. // Function to create RandomAffineOperation.
  137. std::shared_ptr<RandomAffineOperation> RandomAffine(const std::vector<float_t> &degrees,
  138. const std::vector<float_t> &translate_range,
  139. const std::vector<float_t> &scale_range,
  140. const std::vector<float_t> &shear_ranges,
  141. InterpolationMode interpolation,
  142. const std::vector<uint8_t> &fill_value) {
  143. auto op = std::make_shared<RandomAffineOperation>(degrees, translate_range, scale_range, shear_ranges, interpolation,
  144. fill_value);
  145. // Input validation
  146. if (!op->ValidateParams()) {
  147. return nullptr;
  148. }
  149. return op;
  150. }
  151. // Function to create RandomColorOperation.
  152. std::shared_ptr<RandomColorOperation> RandomColor(float t_lb, float t_ub) {
  153. auto op = std::make_shared<RandomColorOperation>(t_lb, t_ub);
  154. // Input validation
  155. if (!op->ValidateParams()) {
  156. return nullptr;
  157. }
  158. return op;
  159. }
  160. std::shared_ptr<TensorOp> RandomColorOperation::Build() {
  161. std::shared_ptr<RandomColorOp> tensor_op = std::make_shared<RandomColorOp>(t_lb_, t_ub_);
  162. return tensor_op;
  163. }
  164. // Function to create RandomColorAdjustOperation.
  165. std::shared_ptr<RandomColorAdjustOperation> RandomColorAdjust(std::vector<float> brightness,
  166. std::vector<float> contrast,
  167. std::vector<float> saturation, std::vector<float> hue) {
  168. auto op = std::make_shared<RandomColorAdjustOperation>(brightness, contrast, saturation, hue);
  169. // Input validation
  170. if (!op->ValidateParams()) {
  171. return nullptr;
  172. }
  173. return op;
  174. }
  175. // Function to create RandomCropOperation.
  176. std::shared_ptr<RandomCropOperation> RandomCrop(std::vector<int32_t> size, std::vector<int32_t> padding,
  177. bool pad_if_needed, std::vector<uint8_t> fill_value,
  178. BorderType padding_mode) {
  179. auto op = std::make_shared<RandomCropOperation>(size, padding, pad_if_needed, fill_value, padding_mode);
  180. // Input validation
  181. if (!op->ValidateParams()) {
  182. return nullptr;
  183. }
  184. return op;
  185. }
  186. // Function to create RandomCropDecodeResizeOperation.
  187. std::shared_ptr<RandomCropDecodeResizeOperation> RandomCropDecodeResize(std::vector<int32_t> size,
  188. std::vector<float> scale,
  189. std::vector<float> ratio,
  190. InterpolationMode interpolation,
  191. int32_t max_attempts) {
  192. auto op = std::make_shared<RandomCropDecodeResizeOperation>(size, scale, ratio, interpolation, max_attempts);
  193. // Input validation
  194. if (!op->ValidateParams()) {
  195. return nullptr;
  196. }
  197. return op;
  198. }
  199. // Function to create RandomHorizontalFlipOperation.
  200. std::shared_ptr<RandomHorizontalFlipOperation> RandomHorizontalFlip(float prob) {
  201. auto op = std::make_shared<RandomHorizontalFlipOperation>(prob);
  202. // Input validation
  203. if (!op->ValidateParams()) {
  204. return nullptr;
  205. }
  206. return op;
  207. }
  208. // Function to create RandomPosterizeOperation.
  209. std::shared_ptr<RandomPosterizeOperation> RandomPosterize(const std::vector<uint8_t> &bit_range) {
  210. auto op = std::make_shared<RandomPosterizeOperation>(bit_range);
  211. // Input validation
  212. if (!op->ValidateParams()) {
  213. return nullptr;
  214. }
  215. return op;
  216. }
  217. // Function to create RandomResizedCropOperation.
  218. std::shared_ptr<RandomResizedCropOperation> RandomResizedCrop(std::vector<int32_t> size, std::vector<float> scale,
  219. std::vector<float> ratio, InterpolationMode interpolation,
  220. int32_t max_attempts) {
  221. auto op = std::make_shared<RandomResizedCropOperation>(size, scale, ratio, interpolation, max_attempts);
  222. // Input validation
  223. if (!op->ValidateParams()) {
  224. return nullptr;
  225. }
  226. return op;
  227. }
  228. // Function to create RandomRotationOperation.
  229. std::shared_ptr<RandomRotationOperation> RandomRotation(std::vector<float> degrees, InterpolationMode resample,
  230. bool expand, std::vector<float> center,
  231. std::vector<uint8_t> fill_value) {
  232. auto op = std::make_shared<RandomRotationOperation>(degrees, resample, expand, center, fill_value);
  233. // Input validation
  234. if (!op->ValidateParams()) {
  235. return nullptr;
  236. }
  237. return op;
  238. }
  239. // Function to create RandomSharpnessOperation.
  240. std::shared_ptr<RandomSharpnessOperation> RandomSharpness(std::vector<float> degrees) {
  241. auto op = std::make_shared<RandomSharpnessOperation>(degrees);
  242. // Input validation
  243. if (!op->ValidateParams()) {
  244. return nullptr;
  245. }
  246. return op;
  247. }
  248. // Function to create RandomSolarizeOperation.
  249. std::shared_ptr<RandomSolarizeOperation> RandomSolarize(std::vector<uint8_t> threshold) {
  250. auto op = std::make_shared<RandomSolarizeOperation>(threshold);
  251. // Input validation
  252. if (!op->ValidateParams()) {
  253. return nullptr;
  254. }
  255. return op;
  256. }
  257. // Function to create RandomVerticalFlipOperation.
  258. std::shared_ptr<RandomVerticalFlipOperation> RandomVerticalFlip(float prob) {
  259. auto op = std::make_shared<RandomVerticalFlipOperation>(prob);
  260. // Input validation
  261. if (!op->ValidateParams()) {
  262. return nullptr;
  263. }
  264. return op;
  265. }
  266. // Function to create RescaleOperation.
  267. std::shared_ptr<RescaleOperation> Rescale(float rescale, float shift) {
  268. auto op = std::make_shared<RescaleOperation>(rescale, shift);
  269. // Input validation
  270. if (!op->ValidateParams()) {
  271. return nullptr;
  272. }
  273. return op;
  274. }
  275. // Function to create ResizeOperation.
  276. std::shared_ptr<ResizeOperation> Resize(std::vector<int32_t> size, InterpolationMode interpolation) {
  277. auto op = std::make_shared<ResizeOperation>(size, interpolation);
  278. // Input validation
  279. if (!op->ValidateParams()) {
  280. return nullptr;
  281. }
  282. return op;
  283. }
  284. // Function to create RgbaToBgrOperation.
  285. std::shared_ptr<RgbaToBgrOperation> RGBA2BGR() {
  286. auto op = std::make_shared<RgbaToBgrOperation>();
  287. // Input validation
  288. if (!op->ValidateParams()) {
  289. return nullptr;
  290. }
  291. return op;
  292. }
  293. // Function to create RgbaToRgbOperation.
  294. std::shared_ptr<RgbaToRgbOperation> RGBA2RGB() {
  295. auto op = std::make_shared<RgbaToRgbOperation>();
  296. // Input validation
  297. if (!op->ValidateParams()) {
  298. return nullptr;
  299. }
  300. return op;
  301. }
  302. // Function to create SwapRedBlueOperation.
  303. std::shared_ptr<SwapRedBlueOperation> SwapRedBlue() {
  304. auto op = std::make_shared<SwapRedBlueOperation>();
  305. // Input validation
  306. if (!op->ValidateParams()) {
  307. return nullptr;
  308. }
  309. return op;
  310. }
  311. // Function to create UniformAugOperation.
  312. std::shared_ptr<UniformAugOperation> UniformAugment(std::vector<std::shared_ptr<TensorOperation>> transforms,
  313. int32_t num_ops) {
  314. auto op = std::make_shared<UniformAugOperation>(transforms, num_ops);
  315. // Input validation
  316. if (!op->ValidateParams()) {
  317. return nullptr;
  318. }
  319. return op;
  320. }
  321. /* ####################################### Validator Functions ############################################ */
  322. Status ValidateVectorPositive(const std::string &dataset_name, const std::vector<int32_t> &size) {
  323. for (int32_t i = 0; i < size.size(); ++i) {
  324. if (size[i] <= 0) {
  325. std::string err_msg =
  326. dataset_name + ": Non-positive size value: " + std::to_string(size[i]) + " at element: " + std::to_string(i);
  327. MS_LOG(ERROR) << err_msg;
  328. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  329. }
  330. }
  331. return Status::OK();
  332. }
  333. bool CmpFloat(const float &a, const float &b, float epsilon = 0.0000000001f) { return (std::fabs(a - b) < epsilon); }
  334. /* ####################################### Derived TensorOperation classes ################################# */
  335. // (In alphabetical order)
  336. // CenterCropOperation
  337. CenterCropOperation::CenterCropOperation(std::vector<int32_t> size) : size_(size) {}
  338. Status CenterCropOperation::ValidateParams() {
  339. if (size_.empty() || size_.size() > 2) {
  340. std::string err_msg = "CenterCrop: size vector has incorrect size.";
  341. MS_LOG(ERROR) << err_msg;
  342. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  343. }
  344. // We have to limit crop size due to library restrictions, optimized to only iterate over size_ once
  345. for (int32_t i = 0; i < size_.size(); ++i) {
  346. if (size_[i] <= 0) {
  347. std::string err_msg = "CenterCrop: invalid size, size must be greater than 0, got: " + std::to_string(size_[i]);
  348. MS_LOG(ERROR) << err_msg;
  349. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  350. }
  351. if (size_[i] == INT_MAX) {
  352. std::string err_msg = "CenterCrop: invalid size, size too large, got: " + std::to_string(size_[i]);
  353. MS_LOG(ERROR) << err_msg;
  354. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  355. }
  356. }
  357. return Status::OK();
  358. }
  359. std::shared_ptr<TensorOp> CenterCropOperation::Build() {
  360. int32_t crop_height = size_[0];
  361. int32_t crop_width = size_[0];
  362. // User has specified crop_width.
  363. if (size_.size() == 2) {
  364. crop_width = size_[1];
  365. }
  366. std::shared_ptr<CenterCropOp> tensor_op = std::make_shared<CenterCropOp>(crop_height, crop_width);
  367. return tensor_op;
  368. }
  369. // CropOperation.
  370. CropOperation::CropOperation(std::vector<int32_t> coordinates, std::vector<int32_t> size)
  371. : coordinates_(coordinates), size_(size) {}
  372. Status CropOperation::ValidateParams() {
  373. // Do some input validation.
  374. if (coordinates_.size() != 2) {
  375. std::string err_msg = "Crop: coordinates must be a vector of two values";
  376. MS_LOG(ERROR) << err_msg;
  377. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  378. }
  379. // we don't check the coordinates here because we don't have access to image dimensions
  380. if (size_.empty() || size_.size() > 2) {
  381. std::string err_msg = "Crop: size must be a vector of one or two values";
  382. MS_LOG(ERROR) << err_msg;
  383. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  384. }
  385. // We have to limit crop size due to library restrictions, optimized to only iterate over size_ once
  386. for (int32_t i = 0; i < size_.size(); ++i) {
  387. if (size_[i] <= 0) {
  388. std::string err_msg = "Crop: invalid size, size must be greater than 0, got: " + std::to_string(size_[i]);
  389. MS_LOG(ERROR) << err_msg;
  390. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  391. }
  392. if (size_[i] == INT_MAX) {
  393. std::string err_msg = "Crop: invalid size, size too large, got: " + std::to_string(size_[i]);
  394. MS_LOG(ERROR) << err_msg;
  395. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  396. }
  397. }
  398. for (int32_t j = 0; j < coordinates_.size(); ++j) {
  399. if (coordinates_[j] < 0) {
  400. std::string err_msg =
  401. "Crop: invalid coordinates, coordinates must be greater than 0, got: " + std::to_string(coordinates_[j]);
  402. MS_LOG(ERROR) << err_msg;
  403. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  404. }
  405. }
  406. return Status::OK();
  407. }
  408. std::shared_ptr<TensorOp> CropOperation::Build() {
  409. int32_t x, y, height, width;
  410. x = coordinates_[0];
  411. y = coordinates_[1];
  412. height = size_[0];
  413. width = size_[0];
  414. if (size_.size() == 2) {
  415. width = size_[1];
  416. }
  417. std::shared_ptr<CropOp> tensor_op = std::make_shared<CropOp>(x, y, height, width);
  418. return tensor_op;
  419. }
  420. // CutMixBatchOperation
  421. CutMixBatchOperation::CutMixBatchOperation(ImageBatchFormat image_batch_format, float alpha, float prob)
  422. : image_batch_format_(image_batch_format), alpha_(alpha), prob_(prob) {}
  423. Status CutMixBatchOperation::ValidateParams() {
  424. if (alpha_ <= 0) {
  425. std::string err_msg =
  426. "CutMixBatch: alpha must be a positive floating value however it is: " + std::to_string(alpha_);
  427. MS_LOG(ERROR) << err_msg;
  428. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  429. }
  430. if (prob_ < 0 || prob_ > 1) {
  431. std::string err_msg = "CutMixBatch: Probability has to be between 0 and 1.";
  432. MS_LOG(ERROR) << err_msg;
  433. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  434. }
  435. return Status::OK();
  436. }
  437. std::shared_ptr<TensorOp> CutMixBatchOperation::Build() {
  438. std::shared_ptr<CutMixBatchOp> tensor_op = std::make_shared<CutMixBatchOp>(image_batch_format_, alpha_, prob_);
  439. return tensor_op;
  440. }
  441. // CutOutOperation
  442. CutOutOperation::CutOutOperation(int32_t length, int32_t num_patches) : length_(length), num_patches_(num_patches) {}
  443. Status CutOutOperation::ValidateParams() {
  444. if (length_ <= 0) {
  445. std::string err_msg = "CutOut: length must be positive, got: " + std::to_string(length_);
  446. MS_LOG(ERROR) << err_msg;
  447. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  448. }
  449. if (num_patches_ <= 0) {
  450. std::string err_msg = "CutOut: number of patches must be positive, got: " + std::to_string(num_patches_);
  451. MS_LOG(ERROR) << err_msg;
  452. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  453. }
  454. return Status::OK();
  455. }
  456. std::shared_ptr<TensorOp> CutOutOperation::Build() {
  457. std::shared_ptr<CutOutOp> tensor_op = std::make_shared<CutOutOp>(length_, length_, num_patches_, false, 0, 0, 0);
  458. return tensor_op;
  459. }
  460. // DecodeOperation
  461. DecodeOperation::DecodeOperation(bool rgb) : rgb_(rgb) {}
  462. Status DecodeOperation::ValidateParams() { return Status::OK(); }
  463. std::shared_ptr<TensorOp> DecodeOperation::Build() { return std::make_shared<DecodeOp>(rgb_); }
  464. // HwcToChwOperation
  465. Status HwcToChwOperation::ValidateParams() { return Status::OK(); }
  466. std::shared_ptr<TensorOp> HwcToChwOperation::Build() { return std::make_shared<HwcToChwOp>(); }
  467. // MixUpOperation
  468. MixUpBatchOperation::MixUpBatchOperation(float alpha) : alpha_(alpha) {}
  469. Status MixUpBatchOperation::ValidateParams() {
  470. if (alpha_ <= 0) {
  471. std::string err_msg =
  472. "MixUpBatch: alpha must be a positive floating value however it is: " + std::to_string(alpha_);
  473. MS_LOG(ERROR) << err_msg;
  474. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  475. }
  476. return Status::OK();
  477. }
  478. std::shared_ptr<TensorOp> MixUpBatchOperation::Build() { return std::make_shared<MixUpBatchOp>(alpha_); }
  479. // NormalizeOperation
  480. NormalizeOperation::NormalizeOperation(std::vector<float> mean, std::vector<float> std) : mean_(mean), std_(std) {}
  481. Status NormalizeOperation::ValidateParams() {
  482. if (mean_.size() != 3) {
  483. std::string err_msg = "Normalize: mean vector has incorrect size: " + std::to_string(mean_.size());
  484. MS_LOG(ERROR) << err_msg;
  485. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  486. }
  487. if (std_.size() != 3) {
  488. std::string err_msg = "Normalize: std vector has incorrect size: " + std::to_string(std_.size());
  489. MS_LOG(ERROR) << err_msg;
  490. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  491. }
  492. // check std/mean value
  493. for (int32_t i = 0; i < std_.size(); ++i) {
  494. if (std_[i] < 0.0f || std_[i] > 255.0f || CmpFloat(std_[i], 0.0f)) {
  495. std::string err_msg = "Normalize: std vector has incorrect value: " + std::to_string(std_[i]);
  496. MS_LOG(ERROR) << err_msg;
  497. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  498. }
  499. if (mean_[i] < 0.0f || mean_[i] > 255.0f || CmpFloat(mean_[i], 0.0f)) {
  500. std::string err_msg = "Normalize: mean vector has incorrect value: " + std::to_string(std_[i]);
  501. MS_LOG(ERROR) << err_msg;
  502. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  503. }
  504. }
  505. return Status::OK();
  506. }
  507. std::shared_ptr<TensorOp> NormalizeOperation::Build() {
  508. return std::make_shared<NormalizeOp>(mean_[0], mean_[1], mean_[2], std_[0], std_[1], std_[2]);
  509. }
  510. // PadOperation
  511. PadOperation::PadOperation(std::vector<int32_t> padding, std::vector<uint8_t> fill_value, BorderType padding_mode)
  512. : padding_(padding), fill_value_(fill_value), padding_mode_(padding_mode) {}
  513. Status PadOperation::ValidateParams() {
  514. // padding
  515. if (padding_.empty() || padding_.size() == 3 || padding_.size() > 4) {
  516. std::string err_msg = "Pad: padding vector has incorrect size: " + std::to_string(padding_.size());
  517. MS_LOG(ERROR) << err_msg;
  518. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  519. }
  520. for (int32_t i = 0; i < padding_.size(); ++i) {
  521. if (padding_[i] < 0) {
  522. std::string err_msg =
  523. "Pad: invalid padding, padding value must be greater than or equal to 0, got: " + std::to_string(padding_[i]);
  524. MS_LOG(ERROR) << err_msg;
  525. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  526. }
  527. if (padding_[i] == INT_MAX) {
  528. std::string err_msg = "Pad: invalid padding, padding value too large, got: " + std::to_string(padding_[i]);
  529. MS_LOG(ERROR) << err_msg;
  530. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  531. }
  532. }
  533. // fill_value
  534. if (fill_value_.empty() || (fill_value_.size() != 1 && fill_value_.size() != 3)) {
  535. std::string err_msg = "Pad: fill_value vector has incorrect size: " + std::to_string(fill_value_.size());
  536. MS_LOG(ERROR) << err_msg;
  537. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  538. }
  539. for (int32_t i = 0; i < fill_value_.size(); ++i) {
  540. if (fill_value_[i] < 0 || fill_value_[i] > 255) {
  541. std::string err_msg = "Pad: fill_value has to be between 0 and 255, got:" + std::to_string(fill_value_[i]);
  542. MS_LOG(ERROR) << err_msg;
  543. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  544. }
  545. }
  546. return Status::OK();
  547. }
  548. std::shared_ptr<TensorOp> PadOperation::Build() {
  549. int32_t pad_top, pad_bottom, pad_left, pad_right;
  550. switch (padding_.size()) {
  551. case 1:
  552. pad_left = padding_[0];
  553. pad_top = padding_[0];
  554. pad_right = padding_[0];
  555. pad_bottom = padding_[0];
  556. break;
  557. case 2:
  558. pad_left = padding_[0];
  559. pad_top = padding_[1];
  560. pad_right = padding_[0];
  561. pad_bottom = padding_[1];
  562. break;
  563. default:
  564. pad_left = padding_[0];
  565. pad_top = padding_[1];
  566. pad_right = padding_[2];
  567. pad_bottom = padding_[3];
  568. }
  569. uint8_t fill_r, fill_g, fill_b;
  570. fill_r = fill_value_[0];
  571. fill_g = fill_value_[0];
  572. fill_b = fill_value_[0];
  573. if (fill_value_.size() == 3) {
  574. fill_r = fill_value_[0];
  575. fill_g = fill_value_[1];
  576. fill_b = fill_value_[2];
  577. }
  578. std::shared_ptr<PadOp> tensor_op =
  579. std::make_shared<PadOp>(pad_top, pad_bottom, pad_left, pad_right, padding_mode_, fill_r, fill_g, fill_b);
  580. return tensor_op;
  581. }
  582. // RandomAffineOperation
  583. RandomAffineOperation::RandomAffineOperation(const std::vector<float_t> &degrees,
  584. const std::vector<float_t> &translate_range,
  585. const std::vector<float_t> &scale_range,
  586. const std::vector<float_t> &shear_ranges, InterpolationMode interpolation,
  587. const std::vector<uint8_t> &fill_value)
  588. : degrees_(degrees),
  589. translate_range_(translate_range),
  590. scale_range_(scale_range),
  591. shear_ranges_(shear_ranges),
  592. interpolation_(interpolation),
  593. fill_value_(fill_value) {}
  594. Status RandomAffineOperation::ValidateParams() {
  595. // Degrees
  596. if (degrees_.size() != 2) {
  597. std::string err_msg =
  598. "RandomAffine: degrees expecting size 2, got: degrees.size() = " + std::to_string(degrees_.size());
  599. MS_LOG(ERROR) << err_msg;
  600. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  601. }
  602. if (degrees_[0] > degrees_[1]) {
  603. std::string err_msg =
  604. "RandomAffine: minimum of degrees range is greater than maximum: min = " + std::to_string(degrees_[0]) +
  605. ", max = " + std::to_string(degrees_[1]);
  606. MS_LOG(ERROR) << err_msg;
  607. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  608. }
  609. // Translate
  610. if (translate_range_.size() != 2 && translate_range_.size() != 4) {
  611. std::string err_msg = "RandomAffine: translate_range expecting size 2 or 4, got: translate_range.size() = " +
  612. std::to_string(translate_range_.size());
  613. MS_LOG(ERROR) << err_msg;
  614. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  615. }
  616. if (translate_range_[0] > translate_range_[1]) {
  617. std::string err_msg = "RandomAffine: minimum of translate range on x is greater than maximum: min = " +
  618. std::to_string(translate_range_[0]) + ", max = " + std::to_string(translate_range_[1]);
  619. MS_LOG(ERROR) << err_msg;
  620. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  621. }
  622. if (translate_range_[0] < -1 || translate_range_[0] > 1) {
  623. std::string err_msg = "RandomAffine: minimum of translate range on x is out of range of [-1, 1], value = " +
  624. std::to_string(translate_range_[0]);
  625. MS_LOG(ERROR) << err_msg;
  626. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  627. }
  628. if (translate_range_[1] < -1 || translate_range_[1] > 1) {
  629. std::string err_msg = "RandomAffine: maximum of translate range on x is out of range of [-1, 1], value = " +
  630. std::to_string(translate_range_[1]);
  631. MS_LOG(ERROR) << err_msg;
  632. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  633. }
  634. if (translate_range_.size() == 4) {
  635. if (translate_range_[2] > translate_range_[3]) {
  636. std::string err_msg = "RandomAffine: minimum of translate range on y is greater than maximum: min = " +
  637. std::to_string(translate_range_[2]) + ", max = " + std::to_string(translate_range_[3]);
  638. MS_LOG(ERROR) << err_msg;
  639. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  640. }
  641. if (translate_range_[2] < -1 || translate_range_[2] > 1) {
  642. std::string err_msg = "RandomAffine: minimum of translate range on y is out of range of [-1, 1], value = " +
  643. std::to_string(translate_range_[2]);
  644. MS_LOG(ERROR) << err_msg;
  645. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  646. }
  647. if (translate_range_[3] < -1 || translate_range_[3] > 1) {
  648. std::string err_msg = "RandomAffine: maximum of translate range on y is out of range of [-1, 1], value = " +
  649. std::to_string(translate_range_[3]);
  650. MS_LOG(ERROR) << err_msg;
  651. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  652. }
  653. }
  654. // Scale
  655. if (scale_range_.size() != 2) {
  656. std::string err_msg = "RandomAffine: scale_range vector has incorrect size: scale_range.size() = " +
  657. std::to_string(scale_range_.size());
  658. MS_LOG(ERROR) << err_msg;
  659. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  660. }
  661. for (int32_t i = 0; i < scale_range_.size(); ++i) {
  662. if (scale_range_[i] <= 0) {
  663. std::string err_msg =
  664. "RandomAffine: scale must be greater than or equal to 0, got:" + std::to_string(fill_value_[i]);
  665. MS_LOG(ERROR) << err_msg;
  666. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  667. }
  668. }
  669. if (scale_range_[0] > scale_range_[1]) {
  670. std::string err_msg =
  671. "RandomAffine: minimum of scale range is greater than maximum: min = " + std::to_string(scale_range_[0]) +
  672. ", max = " + std::to_string(scale_range_[1]);
  673. MS_LOG(ERROR) << err_msg;
  674. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  675. }
  676. // Shear
  677. if (shear_ranges_.size() != 2 && shear_ranges_.size() != 4) {
  678. std::string err_msg = "RandomAffine: shear_ranges expecting size 2 or 4, got: shear_ranges.size() = " +
  679. std::to_string(shear_ranges_.size());
  680. MS_LOG(ERROR) << err_msg;
  681. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  682. }
  683. if (shear_ranges_[0] > shear_ranges_[1]) {
  684. std::string err_msg = "RandomAffine: minimum of horizontal shear range is greater than maximum: min = " +
  685. std::to_string(shear_ranges_[0]) + ", max = " + std::to_string(shear_ranges_[1]);
  686. MS_LOG(ERROR) << err_msg;
  687. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  688. }
  689. if (shear_ranges_.size() == 4 && shear_ranges_[2] > shear_ranges_[3]) {
  690. std::string err_msg = "RandomAffine: minimum of vertical shear range is greater than maximum: min = " +
  691. std::to_string(shear_ranges_[2]) + ", max = " + std::to_string(scale_range_[3]);
  692. MS_LOG(ERROR) << err_msg;
  693. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  694. }
  695. // Fill Value
  696. if (fill_value_.size() != 3) {
  697. std::string err_msg =
  698. "RandomAffine: fill_value vector has incorrect size: fill_value.size() = " + std::to_string(fill_value_.size());
  699. MS_LOG(ERROR) << err_msg;
  700. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  701. }
  702. for (int32_t i = 0; i < fill_value_.size(); ++i) {
  703. if (fill_value_[i] < 0 || fill_value_[i] > 255) {
  704. std::string err_msg =
  705. "RandomAffine: fill_value has to be between 0 and 255, got:" + std::to_string(fill_value_[i]);
  706. MS_LOG(ERROR) << err_msg;
  707. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  708. }
  709. }
  710. return Status::OK();
  711. }
  712. std::shared_ptr<TensorOp> RandomAffineOperation::Build() {
  713. if (shear_ranges_.size() == 2) {
  714. shear_ranges_.resize(4);
  715. }
  716. if (translate_range_.size() == 2) {
  717. translate_range_.resize(4);
  718. }
  719. auto tensor_op = std::make_shared<RandomAffineOp>(degrees_, translate_range_, scale_range_, shear_ranges_,
  720. interpolation_, fill_value_);
  721. return tensor_op;
  722. }
  723. // RandomColorOperation.
  724. RandomColorOperation::RandomColorOperation(float t_lb, float t_ub) : t_lb_(t_lb), t_ub_(t_ub) {}
  725. Status RandomColorOperation::ValidateParams() {
  726. // Do some input validation.
  727. if (t_lb_ < 0 || t_ub_ < 0) {
  728. std::string err_msg =
  729. "RandomColor: lower bound or upper bound must be greater than or equal to 0, got t_lb: " + std::to_string(t_lb_) +
  730. ", t_ub: " + std::to_string(t_ub_);
  731. MS_LOG(ERROR) << err_msg;
  732. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  733. }
  734. if (t_lb_ > t_ub_) {
  735. std::string err_msg =
  736. "RandomColor: lower bound must be less or equal to upper bound, got t_lb: " + std::to_string(t_lb_) +
  737. ", t_ub: " + std::to_string(t_ub_);
  738. MS_LOG(ERROR) << err_msg;
  739. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  740. }
  741. return Status::OK();
  742. }
  743. // RandomColorAdjustOperation.
  744. RandomColorAdjustOperation::RandomColorAdjustOperation(std::vector<float> brightness, std::vector<float> contrast,
  745. std::vector<float> saturation, std::vector<float> hue)
  746. : brightness_(brightness), contrast_(contrast), saturation_(saturation), hue_(hue) {}
  747. Status RandomColorAdjustOperation::ValidateParams() {
  748. // brightness
  749. if (brightness_.empty() || brightness_.size() > 2) {
  750. std::string err_msg =
  751. "RandomColorAdjust: brightness must be a vector of one or two values, got: " + std::to_string(brightness_.size());
  752. MS_LOG(ERROR) << err_msg;
  753. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  754. }
  755. for (int32_t i = 0; i < brightness_.size(); ++i) {
  756. if (brightness_[i] < 0) {
  757. std::string err_msg =
  758. "RandomColorAdjust: brightness must be greater than or equal to 0, got: " + std::to_string(brightness_[i]);
  759. MS_LOG(ERROR) << err_msg;
  760. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  761. }
  762. }
  763. if (brightness_.size() == 2 && (brightness_[0] > brightness_[1])) {
  764. std::string err_msg = "RandomColorAdjust: brightness lower bound must be less or equal to upper bound, got lb: " +
  765. std::to_string(brightness_[0]) + ", ub: " + std::to_string(brightness_[1]);
  766. MS_LOG(ERROR) << err_msg;
  767. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  768. }
  769. // contrast
  770. if (contrast_.empty() || contrast_.size() > 2) {
  771. std::string err_msg =
  772. "RandomColorAdjust: contrast must be a vector of one or two values, got: " + std::to_string(contrast_.size());
  773. MS_LOG(ERROR) << err_msg;
  774. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  775. }
  776. for (int32_t i = 0; i < contrast_.size(); ++i) {
  777. if (contrast_[i] < 0) {
  778. std::string err_msg =
  779. "RandomColorAdjust: contrast must be greater than or equal to 0, got: " + std::to_string(contrast_[i]);
  780. MS_LOG(ERROR) << err_msg;
  781. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  782. }
  783. }
  784. if (contrast_.size() == 2 && (contrast_[0] > contrast_[1])) {
  785. std::string err_msg = "RandomColorAdjust: contrast lower bound must be less or equal to upper bound, got lb: " +
  786. std::to_string(contrast_[0]) + ", ub: " + std::to_string(contrast_[1]);
  787. MS_LOG(ERROR) << err_msg;
  788. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  789. }
  790. // saturation
  791. if (saturation_.empty() || saturation_.size() > 2) {
  792. std::string err_msg =
  793. "RandomColorAdjust: saturation must be a vector of one or two values, got: " + std::to_string(saturation_.size());
  794. MS_LOG(ERROR) << err_msg;
  795. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  796. }
  797. for (int32_t i = 0; i < saturation_.size(); ++i) {
  798. if (saturation_[i] < 0) {
  799. std::string err_msg =
  800. "RandomColorAdjust: saturation must be greater than or equal to 0, got: " + std::to_string(saturation_[i]);
  801. MS_LOG(ERROR) << err_msg;
  802. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  803. }
  804. }
  805. if (saturation_.size() == 2 && (saturation_[0] > saturation_[1])) {
  806. std::string err_msg = "RandomColorAdjust: saturation lower bound must be less or equal to upper bound, got lb: " +
  807. std::to_string(saturation_[0]) + ", ub: " + std::to_string(saturation_[1]);
  808. MS_LOG(ERROR) << err_msg;
  809. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  810. }
  811. // hue
  812. if (hue_.empty() || hue_.size() > 2) {
  813. std::string err_msg =
  814. "RandomColorAdjust: hue must be a vector of one or two values, got: " + std::to_string(hue_.size());
  815. MS_LOG(ERROR) << err_msg;
  816. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  817. }
  818. for (int32_t i = 0; i < hue_.size(); ++i) {
  819. if (hue_[i] < -0.5 || hue_[i] > 0.5) {
  820. std::string err_msg = "RandomColorAdjust: hue has to be between -0.5 and 0.5, got: " + std::to_string(hue_[i]);
  821. MS_LOG(ERROR) << err_msg;
  822. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  823. }
  824. }
  825. if (hue_.size() == 2 && (hue_[0] > hue_[1])) {
  826. std::string err_msg =
  827. "RandomColorAdjust: hue lower bound must be less or equal to upper bound, got lb: " + std::to_string(hue_[0]) +
  828. ", ub: " + std::to_string(hue_[1]);
  829. MS_LOG(ERROR) << err_msg;
  830. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  831. }
  832. return Status::OK();
  833. }
  834. std::shared_ptr<TensorOp> RandomColorAdjustOperation::Build() {
  835. float brightness_lb, brightness_ub, contrast_lb, contrast_ub, saturation_lb, saturation_ub, hue_lb, hue_ub;
  836. brightness_lb = brightness_[0];
  837. brightness_ub = brightness_[0];
  838. if (brightness_.size() == 2) brightness_ub = brightness_[1];
  839. contrast_lb = contrast_[0];
  840. contrast_ub = contrast_[0];
  841. if (contrast_.size() == 2) contrast_ub = contrast_[1];
  842. saturation_lb = saturation_[0];
  843. saturation_ub = saturation_[0];
  844. if (saturation_.size() == 2) saturation_ub = saturation_[1];
  845. hue_lb = hue_[0];
  846. hue_ub = hue_[0];
  847. if (hue_.size() == 2) hue_ub = hue_[1];
  848. std::shared_ptr<RandomColorAdjustOp> tensor_op = std::make_shared<RandomColorAdjustOp>(
  849. brightness_lb, brightness_ub, contrast_lb, contrast_ub, saturation_lb, saturation_ub, hue_lb, hue_ub);
  850. return tensor_op;
  851. }
  852. // RandomCropOperation
  853. RandomCropOperation::RandomCropOperation(std::vector<int32_t> size, std::vector<int32_t> padding, bool pad_if_needed,
  854. std::vector<uint8_t> fill_value, BorderType padding_mode)
  855. : size_(size),
  856. padding_(padding),
  857. pad_if_needed_(pad_if_needed),
  858. fill_value_(fill_value),
  859. padding_mode_(padding_mode) {}
  860. Status RandomCropOperation::ValidateParams() {
  861. // size
  862. if (size_.empty() || size_.size() > 2) {
  863. std::string err_msg = "RandomCrop: size must be a vector of one or two values";
  864. MS_LOG(ERROR) << err_msg;
  865. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  866. }
  867. RETURN_IF_NOT_OK(ValidateVectorPositive("RandomCrop", size_));
  868. // padding
  869. if (padding_.empty() || padding_.size() != 4) {
  870. std::string err_msg = "RandomCrop: padding vector has incorrect size: " + std::to_string(padding_.size());
  871. MS_LOG(ERROR) << err_msg;
  872. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  873. }
  874. for (int32_t i = 0; i < padding_.size(); ++i) {
  875. if (padding_[i] < 0) {
  876. std::string err_msg = "RandomCrop: invalid padding, padding value must be greater than or equal to 0, got: " +
  877. std::to_string(padding_[i]);
  878. MS_LOG(ERROR) << err_msg;
  879. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  880. }
  881. if (padding_[i] == INT_MAX) {
  882. std::string err_msg = "RandomCrop: invalid padding, padding value too large, got: " + std::to_string(padding_[i]);
  883. MS_LOG(ERROR) << err_msg;
  884. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  885. }
  886. }
  887. // fill_value
  888. if (fill_value_.empty() || fill_value_.size() != 3) {
  889. std::string err_msg = "RandomCrop: fill_value vector has incorrect size: " + std::to_string(fill_value_.size());
  890. MS_LOG(ERROR) << err_msg;
  891. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  892. }
  893. for (int32_t i = 0; i < fill_value_.size(); ++i) {
  894. if (fill_value_[i] < 0 || fill_value_[i] > 255) {
  895. std::string err_msg = "RandomCrop: fill_value has to be between 0 and 255, got:" + std::to_string(fill_value_[i]);
  896. MS_LOG(ERROR) << err_msg;
  897. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  898. }
  899. }
  900. return Status::OK();
  901. }
  902. std::shared_ptr<TensorOp> RandomCropOperation::Build() {
  903. int32_t crop_height = size_[0];
  904. int32_t crop_width = size_[0];
  905. // User has specified the crop_width value.
  906. if (size_.size() == 2) {
  907. crop_width = size_[1];
  908. }
  909. int32_t pad_top = padding_[0];
  910. int32_t pad_bottom = padding_[1];
  911. int32_t pad_left = padding_[2];
  912. int32_t pad_right = padding_[3];
  913. uint8_t fill_r = fill_value_[0];
  914. uint8_t fill_g = fill_value_[1];
  915. uint8_t fill_b = fill_value_[2];
  916. auto tensor_op = std::make_shared<RandomCropOp>(crop_height, crop_width, pad_top, pad_bottom, pad_left, pad_right,
  917. padding_mode_, pad_if_needed_, fill_r, fill_g, fill_b);
  918. return tensor_op;
  919. }
  920. // RandomCropDecodeResizeOperation
  921. RandomCropDecodeResizeOperation::RandomCropDecodeResizeOperation(std::vector<int32_t> size, std::vector<float> scale,
  922. std::vector<float> ratio,
  923. InterpolationMode interpolation, int32_t max_attempts)
  924. : size_(size), scale_(scale), ratio_(ratio), interpolation_(interpolation), max_attempts_(max_attempts) {}
  925. Status RandomCropDecodeResizeOperation::ValidateParams() {
  926. // size
  927. if (size_.empty() || size_.size() > 2) {
  928. std::string err_msg = "RandomCropDecodeResize: size vector has incorrect size: " + std::to_string(size_.size());
  929. MS_LOG(ERROR) << err_msg;
  930. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  931. }
  932. RETURN_IF_NOT_OK(ValidateVectorPositive("RandomCropDecodeResize", size_));
  933. // rescale
  934. if (scale_.empty() || scale_.size() != 2) {
  935. std::string err_msg = "RandomCropDecodeResize: scale vector has incorrect size: " + std::to_string(scale_.size());
  936. MS_LOG(ERROR) << err_msg;
  937. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  938. }
  939. for (int32_t i = 0; i < scale_.size(); ++i) {
  940. if (scale_[i] < 0) {
  941. std::string err_msg = "RandomCropDecodeResize: invalid scale, scale must be greater than or equal to 0, got: " +
  942. std::to_string(scale_[i]);
  943. MS_LOG(ERROR) << err_msg;
  944. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  945. }
  946. if (scale_[i] == INT_MAX) {
  947. std::string err_msg = "RandomCropDecodeResize: invalid scale, scale too large, got: " + std::to_string(scale_[i]);
  948. MS_LOG(ERROR) << err_msg;
  949. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  950. }
  951. }
  952. if (scale_[0] > scale_[1]) {
  953. std::string err_msg = "RandomCropDecodeResize: scale should be in (min,max) format. Got (max,min).";
  954. MS_LOG(ERROR) << err_msg;
  955. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  956. }
  957. // ratio
  958. if (ratio_.empty() || ratio_.size() != 2) {
  959. std::string err_msg = "RandomCropDecodeResize: ratio vector has incorrect size: " + std::to_string(ratio_.size());
  960. MS_LOG(ERROR) << err_msg;
  961. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  962. }
  963. for (int32_t i = 0; i < ratio_.size(); ++i) {
  964. if (ratio_[i] < 0) {
  965. std::string err_msg = "RandomCropDecodeResize: invalid ratio, ratio must be greater than or equal to 0, got: " +
  966. std::to_string(ratio_[i]);
  967. MS_LOG(ERROR) << err_msg;
  968. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  969. }
  970. if (ratio_[i] == INT_MAX) {
  971. std::string err_msg = "RandomCropDecodeResize: invalid ratio, ratio too large, got: " + std::to_string(ratio_[i]);
  972. MS_LOG(ERROR) << err_msg;
  973. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  974. }
  975. }
  976. if (ratio_[0] > ratio_[1]) {
  977. std::string err_msg = "RandomCropDecodeResize: ratio should be in (min,max) format. Got (max,min).";
  978. MS_LOG(ERROR) << err_msg;
  979. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  980. }
  981. // max_attempts
  982. if (max_attempts_ < 1) {
  983. std::string err_msg =
  984. "RandomCropDecodeResize: max_attempts must be greater than or equal to 1, got: " + std::to_string(max_attempts_);
  985. MS_LOG(ERROR) << err_msg;
  986. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  987. }
  988. return Status::OK();
  989. }
  990. std::shared_ptr<TensorOp> RandomCropDecodeResizeOperation::Build() {
  991. int32_t crop_height = size_[0];
  992. int32_t crop_width = size_[0];
  993. // User has specified the crop_width value.
  994. if (size_.size() == 2) {
  995. crop_width = size_[1];
  996. }
  997. float scale_lower_bound = scale_[0];
  998. float scale_upper_bound = scale_[1];
  999. float aspect_lower_bound = ratio_[0];
  1000. float aspect_upper_bound = ratio_[1];
  1001. auto tensor_op =
  1002. std::make_shared<RandomCropDecodeResizeOp>(crop_height, crop_width, scale_lower_bound, scale_upper_bound,
  1003. aspect_lower_bound, aspect_upper_bound, interpolation_, max_attempts_);
  1004. return tensor_op;
  1005. }
  1006. // RandomHorizontalFlipOperation
  1007. RandomHorizontalFlipOperation::RandomHorizontalFlipOperation(float probability) : probability_(probability) {}
  1008. Status RandomHorizontalFlipOperation::ValidateParams() {
  1009. if (probability_ < 0.0 || probability_ > 1.0) {
  1010. std::string err_msg = "RandomHorizontalFlip: probability must be between 0.0 and 1.0.";
  1011. MS_LOG(ERROR) << err_msg;
  1012. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1013. }
  1014. return Status::OK();
  1015. }
  1016. std::shared_ptr<TensorOp> RandomHorizontalFlipOperation::Build() {
  1017. std::shared_ptr<RandomHorizontalFlipOp> tensor_op = std::make_shared<RandomHorizontalFlipOp>(probability_);
  1018. return tensor_op;
  1019. }
  1020. // RandomPosterizeOperation
  1021. RandomPosterizeOperation::RandomPosterizeOperation(const std::vector<uint8_t> &bit_range) : bit_range_(bit_range) {}
  1022. Status RandomPosterizeOperation::ValidateParams() {
  1023. if (bit_range_.size() != 2) {
  1024. std::string err_msg =
  1025. "RandomPosterize: bit_range needs to be of size 2 but is of size: " + std::to_string(bit_range_.size());
  1026. MS_LOG(ERROR) << err_msg;
  1027. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1028. }
  1029. if (bit_range_[0] < 1 || bit_range_[0] > 8) {
  1030. std::string err_msg = "RandomPosterize: min_bit value is out of range [1-8]: " + std::to_string(bit_range_[0]);
  1031. MS_LOG(ERROR) << err_msg;
  1032. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1033. }
  1034. if (bit_range_[1] < 1 || bit_range_[1] > 8) {
  1035. std::string err_msg = "RandomPosterize: max_bit value is out of range [1-8]: " + std::to_string(bit_range_[1]);
  1036. MS_LOG(ERROR) << err_msg;
  1037. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1038. }
  1039. if (bit_range_[1] < bit_range_[0]) {
  1040. std::string err_msg = "RandomPosterize: max_bit value is less than min_bit: max =" + std::to_string(bit_range_[1]) +
  1041. ", min = " + std::to_string(bit_range_[0]);
  1042. MS_LOG(ERROR) << err_msg;
  1043. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1044. }
  1045. return Status::OK();
  1046. }
  1047. std::shared_ptr<TensorOp> RandomPosterizeOperation::Build() {
  1048. std::shared_ptr<RandomPosterizeOp> tensor_op = std::make_shared<RandomPosterizeOp>(bit_range_);
  1049. return tensor_op;
  1050. }
  1051. // RandomResizedCropOperation
  1052. RandomResizedCropOperation::RandomResizedCropOperation(std::vector<int32_t> size, std::vector<float> scale,
  1053. std::vector<float> ratio, InterpolationMode interpolation,
  1054. int32_t max_attempts)
  1055. : size_(size), scale_(scale), ratio_(ratio), interpolation_(interpolation), max_attempts_(max_attempts) {}
  1056. Status RandomResizedCropOperation::ValidateParams() {
  1057. // size
  1058. if (size_.size() != 2 && size_.size() != 1) {
  1059. std::string err_msg =
  1060. "RandomResizedCrop: size must be a vector of one or two values, got: " + std::to_string(size_.size());
  1061. MS_LOG(ERROR) << err_msg;
  1062. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1063. }
  1064. if (size_[0] <= 0 || (size_.size() == 2 && size_[1] <= 0)) {
  1065. std::string err_msg = "RandomResizedCrop: size must only contain positive integers.";
  1066. MS_LOG(ERROR) << "RandomResizedCrop: size must only contain positive integers, got: " << size_;
  1067. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1068. }
  1069. // scale
  1070. if (scale_.size() != 2) {
  1071. std::string err_msg =
  1072. "RandomResizedCrop: scale must be a vector of two values, got: " + std::to_string(scale_.size());
  1073. MS_LOG(ERROR) << err_msg;
  1074. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1075. }
  1076. if (scale_[0] < 0 || scale_[1] < 0) {
  1077. std::string err_msg = "RandomResizedCrop: scale must be greater than or equal to 0.";
  1078. MS_LOG(ERROR) << "RandomResizedCrop: scale must be greater than or equal to 0, got: " << scale_;
  1079. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1080. }
  1081. if (scale_[1] < scale_[0]) {
  1082. std::string err_msg = "RandomResizedCrop: scale must have a size of two in the format of (min, max).";
  1083. MS_LOG(ERROR) << "RandomResizedCrop: scale must have a size of two in the format of (min, max), but got: "
  1084. << scale_;
  1085. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1086. }
  1087. // ratio
  1088. if (ratio_.size() != 2) {
  1089. std::string err_msg = "RandomResizedCrop: ratio must be in the format of (min, max).";
  1090. MS_LOG(ERROR) << "RandomResizedCrop: ratio must be in the format of (min, max), but got: " << ratio_;
  1091. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1092. }
  1093. if (ratio_[0] < 0 || ratio_[1] < 0) {
  1094. std::string err_msg = "RandomResizedCrop: ratio must be greater than or equal to 0.";
  1095. MS_LOG(ERROR) << "RandomResizedCrop: ratio must be greater than or equal to 0, got: " << ratio_;
  1096. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1097. }
  1098. if (ratio_[1] < ratio_[0]) {
  1099. std::string err_msg = "RandomResizedCrop: ratio must have a size of two in the format of (min, max).";
  1100. MS_LOG(ERROR) << "RandomResizedCrop: ratio must have a size of two in the format of (min, max), but got: "
  1101. << ratio_;
  1102. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1103. }
  1104. return Status::OK();
  1105. }
  1106. std::shared_ptr<TensorOp> RandomResizedCropOperation::Build() {
  1107. int32_t height = size_[0], width = size_[0];
  1108. if (size_.size() == 2) width = size_[1];
  1109. std::shared_ptr<RandomCropAndResizeOp> tensor_op = std::make_shared<RandomCropAndResizeOp>(
  1110. height, width, scale_[0], scale_[1], ratio_[0], ratio_[1], interpolation_, max_attempts_);
  1111. return tensor_op;
  1112. }
  1113. // Function to create RandomRotationOperation.
  1114. RandomRotationOperation::RandomRotationOperation(std::vector<float> degrees, InterpolationMode interpolation_mode,
  1115. bool expand, std::vector<float> center,
  1116. std::vector<uint8_t> fill_value)
  1117. : degrees_(degrees),
  1118. interpolation_mode_(interpolation_mode),
  1119. expand_(expand),
  1120. center_(center),
  1121. fill_value_(fill_value) {}
  1122. Status RandomRotationOperation::ValidateParams() {
  1123. // degrees
  1124. if (degrees_.size() != 2) {
  1125. std::string err_msg =
  1126. "RandomRotation: degrees must be a vector of two values, got: " + std::to_string(degrees_.size());
  1127. MS_LOG(ERROR) << "RandomRotation: degrees must be a vector of two values, got: " << degrees_;
  1128. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1129. }
  1130. if (degrees_[1] < degrees_[0]) {
  1131. std::string err_msg = "RandomRotation: degrees must be in the format of (min, max).";
  1132. MS_LOG(ERROR) << "RandomRotation: degrees must be in the format of (min, max), got: " << degrees_;
  1133. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1134. }
  1135. // center
  1136. if (center_.empty() || center_.size() != 2) {
  1137. std::string err_msg =
  1138. "RandomRotation: center must be a vector of two values, got: " + std::to_string(center_.size());
  1139. MS_LOG(ERROR) << err_msg;
  1140. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1141. }
  1142. // fill_value
  1143. if (fill_value_.empty() || fill_value_.size() != 3) {
  1144. std::string err_msg =
  1145. "RandomRotation: fill_value must be a vector of two values, got: " + std::to_string(fill_value_.size());
  1146. MS_LOG(ERROR) << err_msg;
  1147. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1148. }
  1149. for (int32_t i = 0; i < fill_value_.size(); ++i) {
  1150. if (fill_value_[i] < 0 || fill_value_[i] > 255) {
  1151. std::string err_msg =
  1152. "RandomRotation: fill_value has to be between 0 and 255, got: " + std::to_string(fill_value_[i]);
  1153. MS_LOG(ERROR) << err_msg;
  1154. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1155. }
  1156. }
  1157. return Status::OK();
  1158. }
  1159. std::shared_ptr<TensorOp> RandomRotationOperation::Build() {
  1160. std::shared_ptr<RandomRotationOp> tensor_op =
  1161. std::make_shared<RandomRotationOp>(degrees_[0], degrees_[1], center_[0], center_[1], interpolation_mode_, expand_,
  1162. fill_value_[0], fill_value_[1], fill_value_[2]);
  1163. return tensor_op;
  1164. }
  1165. // Function to create RandomSharpness.
  1166. RandomSharpnessOperation::RandomSharpnessOperation(std::vector<float> degrees) : degrees_(degrees) {}
  1167. Status RandomSharpnessOperation::ValidateParams() {
  1168. if (degrees_.size() != 2 || degrees_[0] < 0 || degrees_[1] < 0) {
  1169. std::string err_msg = "RandomSharpness: degrees must be a vector of two values and greater than or equal to 0.";
  1170. MS_LOG(ERROR) << "RandomSharpness: degrees must be a vector of two values and greater than or equal to 0, got: "
  1171. << degrees_;
  1172. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1173. }
  1174. if (degrees_[1] < degrees_[0]) {
  1175. std::string err_msg = "RandomSharpness: degrees must be in the format of (min, max).";
  1176. MS_LOG(ERROR) << "RandomSharpness: degrees must be in the format of (min, max), got: " << degrees_;
  1177. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1178. }
  1179. return Status::OK();
  1180. }
  1181. std::shared_ptr<TensorOp> RandomSharpnessOperation::Build() {
  1182. std::shared_ptr<RandomSharpnessOp> tensor_op = std::make_shared<RandomSharpnessOp>(degrees_[0], degrees_[1]);
  1183. return tensor_op;
  1184. }
  1185. // RandomSolarizeOperation.
  1186. RandomSolarizeOperation::RandomSolarizeOperation(std::vector<uint8_t> threshold) : threshold_(threshold) {}
  1187. Status RandomSolarizeOperation::ValidateParams() {
  1188. if (threshold_.size() != 2) {
  1189. std::string err_msg =
  1190. "RandomSolarize: threshold must be a vector of two values, got: " + std::to_string(threshold_.size());
  1191. MS_LOG(ERROR) << err_msg;
  1192. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1193. }
  1194. for (int32_t i = 0; i < threshold_.size(); ++i) {
  1195. if (threshold_[i] < 0 || threshold_[i] > 255) {
  1196. std::string err_msg =
  1197. "RandomSolarize: threshold has to be between 0 and 255, got:" + std::to_string(threshold_[i]);
  1198. MS_LOG(ERROR) << err_msg;
  1199. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1200. }
  1201. }
  1202. if (threshold_[0] > threshold_[1]) {
  1203. std::string err_msg = "RandomSolarize: threshold must be passed in a (min, max) format";
  1204. MS_LOG(ERROR) << err_msg;
  1205. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1206. }
  1207. return Status::OK();
  1208. }
  1209. std::shared_ptr<TensorOp> RandomSolarizeOperation::Build() {
  1210. std::shared_ptr<RandomSolarizeOp> tensor_op = std::make_shared<RandomSolarizeOp>(threshold_);
  1211. return tensor_op;
  1212. }
  1213. // RandomVerticalFlipOperation
  1214. RandomVerticalFlipOperation::RandomVerticalFlipOperation(float probability) : probability_(probability) {}
  1215. Status RandomVerticalFlipOperation::ValidateParams() {
  1216. if (probability_ < 0.0 || probability_ > 1.0) {
  1217. std::string err_msg = "RandomVerticalFlip: probability must be between 0.0 and 1.0.";
  1218. MS_LOG(ERROR) << err_msg;
  1219. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1220. }
  1221. return Status::OK();
  1222. }
  1223. std::shared_ptr<TensorOp> RandomVerticalFlipOperation::Build() {
  1224. std::shared_ptr<RandomVerticalFlipOp> tensor_op = std::make_shared<RandomVerticalFlipOp>(probability_);
  1225. return tensor_op;
  1226. }
  1227. // RescaleOperation
  1228. RescaleOperation::RescaleOperation(float rescale, float shift) : rescale_(rescale), shift_(shift) {}
  1229. Status RescaleOperation::ValidateParams() {
  1230. if (rescale_ < 0) {
  1231. std::string err_msg = "Rescale: rescale must be greater than or equal to 0, got: " + std::to_string(rescale_);
  1232. MS_LOG(ERROR) << err_msg;
  1233. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1234. }
  1235. return Status::OK();
  1236. }
  1237. std::shared_ptr<TensorOp> RescaleOperation::Build() {
  1238. std::shared_ptr<RescaleOp> tensor_op = std::make_shared<RescaleOp>(rescale_, shift_);
  1239. return tensor_op;
  1240. }
  1241. // ResizeOperation
  1242. ResizeOperation::ResizeOperation(std::vector<int32_t> size, InterpolationMode interpolation)
  1243. : size_(size), interpolation_(interpolation) {}
  1244. Status ResizeOperation::ValidateParams() {
  1245. // size
  1246. if (size_.empty() || size_.size() > 2) {
  1247. std::string err_msg = "Resize: size must be a vector of one or two values, got: " + std::to_string(size_.size());
  1248. MS_LOG(ERROR) << err_msg;
  1249. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1250. }
  1251. RETURN_IF_NOT_OK(ValidateVectorPositive("Resize", size_));
  1252. return Status::OK();
  1253. }
  1254. std::shared_ptr<TensorOp> ResizeOperation::Build() {
  1255. int32_t height = size_[0];
  1256. int32_t width = 0;
  1257. // User specified the width value.
  1258. if (size_.size() == 2) {
  1259. width = size_[1];
  1260. }
  1261. return std::make_shared<ResizeOp>(height, width, interpolation_);
  1262. }
  1263. // RgbaToBgrOperation.
  1264. RgbaToBgrOperation::RgbaToBgrOperation() {}
  1265. Status RgbaToBgrOperation::ValidateParams() { return Status::OK(); }
  1266. std::shared_ptr<TensorOp> RgbaToBgrOperation::Build() {
  1267. std::shared_ptr<RgbaToBgrOp> tensor_op = std::make_shared<RgbaToBgrOp>();
  1268. return tensor_op;
  1269. }
  1270. // RgbaToRgbOperation.
  1271. RgbaToRgbOperation::RgbaToRgbOperation() {}
  1272. Status RgbaToRgbOperation::ValidateParams() { return Status::OK(); }
  1273. std::shared_ptr<TensorOp> RgbaToRgbOperation::Build() {
  1274. std::shared_ptr<RgbaToRgbOp> tensor_op = std::make_shared<RgbaToRgbOp>();
  1275. return tensor_op;
  1276. }
  1277. // SwapRedBlueOperation.
  1278. SwapRedBlueOperation::SwapRedBlueOperation() {}
  1279. Status SwapRedBlueOperation::ValidateParams() { return Status::OK(); }
  1280. std::shared_ptr<TensorOp> SwapRedBlueOperation::Build() {
  1281. std::shared_ptr<SwapRedBlueOp> tensor_op = std::make_shared<SwapRedBlueOp>();
  1282. return tensor_op;
  1283. }
  1284. // UniformAugOperation
  1285. UniformAugOperation::UniformAugOperation(std::vector<std::shared_ptr<TensorOperation>> transforms, int32_t num_ops)
  1286. : transforms_(transforms), num_ops_(num_ops) {}
  1287. Status UniformAugOperation::ValidateParams() {
  1288. // transforms
  1289. if (num_ops_ > transforms_.size()) {
  1290. std::string err_msg = "UniformAug: num_ops is greater than transforms size, num_ops: " + std::to_string(num_ops_);
  1291. MS_LOG(ERROR) << err_msg;
  1292. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1293. }
  1294. for (int32_t i = 0; i < transforms_.size(); ++i) {
  1295. if (transforms_[i] == nullptr) {
  1296. std::string err_msg = "UniformAug: transform ops must not be null.";
  1297. MS_LOG(ERROR) << err_msg;
  1298. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1299. }
  1300. }
  1301. // num_ops
  1302. if (num_ops_ <= 0) {
  1303. std::string err_msg = "UniformAug: num_ops must be greater than 0, num_ops: " + std::to_string(num_ops_);
  1304. MS_LOG(ERROR) << err_msg;
  1305. RETURN_STATUS_SYNTAX_ERROR(err_msg);
  1306. }
  1307. return Status::OK();
  1308. }
  1309. std::shared_ptr<TensorOp> UniformAugOperation::Build() {
  1310. std::vector<std::shared_ptr<TensorOp>> tensor_ops;
  1311. (void)std::transform(transforms_.begin(), transforms_.end(), std::back_inserter(tensor_ops),
  1312. [](std::shared_ptr<TensorOperation> op) -> std::shared_ptr<TensorOp> { return op->Build(); });
  1313. std::shared_ptr<UniformAugOp> tensor_op = std::make_shared<UniformAugOp>(tensor_ops, num_ops_);
  1314. return tensor_op;
  1315. }
  1316. } // namespace vision
  1317. } // namespace api
  1318. } // namespace dataset
  1319. } // namespace mindspore