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
17 #include "minddata/dataset/kernels/image/random_color_op.h"
18
19 #include "minddata/dataset/core/cv_tensor.h"
20 #include "minddata/dataset/kernels/image/image_utils.h"
21
22 namespace mindspore {
23 namespace dataset {
RandomColorOp(float t_lb,float t_ub)24 RandomColorOp::RandomColorOp(float t_lb, float t_ub) : dist_(t_lb, t_ub), t_lb_(t_lb), t_ub_(t_ub) {}
25
Compute(const std::shared_ptr<Tensor> & input,std::shared_ptr<Tensor> * output)26 Status RandomColorOp::Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) {
27 IO_CHECK(input, output);
28 if (input->Rank() != kDefaultImageRank || input->shape()[kChannelIndexHWC] != kDefaultImageChannel) {
29 RETURN_STATUS_UNEXPECTED(
30 "RandomColor: image shape is not <H,W,C> or channel is not 3, got rank: " + std::to_string(input->Rank()) +
31 ", and channel: " + std::to_string(input->shape()[kChannelIndexHWC]));
32 }
33 // 0.5 pixel precision assuming an 8 bit image
34 const auto eps = 0.00195;
35 const auto t = dist_(random_generator_);
36 if (abs(t - 1.0) < eps) {
37 // Just return input? Can we do it given that input would otherwise get consumed in CVTensor constructor anyway?
38 *output = input;
39 return Status::OK();
40 }
41 auto cvt_in = CVTensor::AsCVTensor(input);
42 auto m1 = cvt_in->mat();
43 cv::Mat gray;
44 // gray is allocated without using the allocator
45 cv::cvtColor(m1, gray, cv::COLOR_RGB2GRAY);
46 // luminosity is not preserved, consider using weights.
47 cv::Mat temp[3] = {gray, gray, gray};
48 cv::Mat cv_out;
49 cv::merge(temp, 3, cv_out);
50 std::shared_ptr<CVTensor> cvt_out;
51 RETURN_IF_NOT_OK(CVTensor::CreateFromMat(cv_out, cvt_in->Rank(), &cvt_out));
52 if (abs(t - 0.0) < eps) {
53 // return grayscale
54 *output = std::static_pointer_cast<Tensor>(cvt_out);
55 return Status::OK();
56 }
57 try {
58 // return blended image. addWeighted takes care of overflow for uint8_t
59 cv::addWeighted(m1, t, cvt_out->mat(), 1 - t, 0, cvt_out->mat());
60 } catch (const cv::Exception &e) {
61 RETURN_STATUS_UNEXPECTED("RandomColorOp: cv::addWeighted " + std::string(e.what()));
62 }
63 *output = std::static_pointer_cast<Tensor>(cvt_out);
64 return Status::OK();
65 }
66 } // namespace dataset
67 } // namespace mindspore
68