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
17 #include "minddata/dataset/kernels/image/random_color_op.h"
18 #include "minddata/dataset/kernels/image/image_utils.h"
19 #include "minddata/dataset/core/cv_tensor.h"
20 namespace mindspore {
21 namespace dataset {
22
RandomColorOp(float t_lb,float t_ub)23 RandomColorOp::RandomColorOp(float t_lb, float t_ub) : rnd_(GetSeed()), dist_(t_lb, t_ub), t_lb_(t_lb), t_ub_(t_ub) {
24 is_deterministic_ = false;
25 }
26
Compute(const std::shared_ptr<Tensor> & in,std::shared_ptr<Tensor> * out)27 Status RandomColorOp::Compute(const std::shared_ptr<Tensor> &in, std::shared_ptr<Tensor> *out) {
28 IO_CHECK(in, out);
29 if (in->Rank() != 3 || in->shape()[2] != 3) {
30 RETURN_STATUS_UNEXPECTED("RandomColor: image shape is not <H,W,C> or channel is not 3, got rank: " +
31 std::to_string(in->Rank()) + ", and channel: " + std::to_string(in->shape()[2]));
32 }
33 // 0.5 pixel precision assuming an 8 bit image
34 const auto eps = 0.00195;
35 const auto t = dist_(rnd_);
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 *out = in;
39 return Status::OK();
40 }
41 auto cvt_in = CVTensor::AsCVTensor(in);
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 *out = 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 *out = std::static_pointer_cast<Tensor>(cvt_out);
64 return Status::OK();
65 }
66
67 } // namespace dataset
68 } // namespace mindspore
69