Home | History | Annotate | Download | only in kernels
      1 /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
      2 
      3 Licensed under the Apache License, Version 2.0 (the "License");
      4 you may not use this file except in compliance with the License.
      5 You may obtain a copy of the License at
      6 
      7     http://www.apache.org/licenses/LICENSE-2.0
      8 
      9 Unless required by applicable law or agreed to in writing, software
     10 distributed under the License is distributed on an "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 See the License for the specific language governing permissions and
     13 limitations under the License.
     14 ==============================================================================*/
     15 
     16 #include "tensorflow/core/framework/allocator.h"
     17 #include "tensorflow/core/framework/fake_input.h"
     18 #include "tensorflow/core/framework/node_def_builder.h"
     19 #include "tensorflow/core/framework/op_kernel.h"
     20 #include "tensorflow/core/framework/tensor.h"
     21 #include "tensorflow/core/framework/tensor_testutil.h"
     22 #include "tensorflow/core/framework/types.h"
     23 #include "tensorflow/core/framework/types.pb.h"
     24 #include "tensorflow/core/kernels/ops_testutil.h"
     25 #include "tensorflow/core/kernels/ops_util.h"
     26 #include "tensorflow/core/lib/core/status_test_util.h"
     27 #include "tensorflow/core/platform/test.h"
     28 
     29 namespace tensorflow {
     30 
     31 template <typename T>
     32 class RGBToHSVOpTest : public OpsTestBase {
     33  protected:
     34   void MakeOp(DataType data_type) {
     35     TF_EXPECT_OK(NodeDefBuilder("rgb_to_hsv_op", "RGBToHSV")
     36                      .Input(FakeInput(data_type))
     37                      .Finalize(node_def()));
     38     TF_EXPECT_OK(InitOp());
     39   }
     40 
     41   void CheckBlack(DataType data_type) {
     42     // Black pixel should map to hsv = [0,0,0]
     43     AddInputFromArray<T>(TensorShape({3}), {0, 0, 0});
     44     TF_ASSERT_OK(RunOpKernel());
     45 
     46     Tensor expected(allocator(), data_type, TensorShape({3}));
     47     test::FillValues<T>(&expected, {0.0, 0.0, 0.0});
     48     test::ExpectTensorEqual<T>(expected, *GetOutput(0));
     49   }
     50 
     51   void CheckGray(DataType data_type) {
     52     // Gray pixel should have hue = saturation = 0.0, value = r/255
     53     AddInputFromArray<T>(TensorShape({3}), {.5, .5, .5});
     54     TF_ASSERT_OK(RunOpKernel());
     55 
     56     Tensor expected(allocator(), data_type, TensorShape({3}));
     57     test::FillValues<T>(&expected, {0.0, 0.0, .5});
     58     test::ExpectTensorEqual<T>(expected, *GetOutput(0));
     59   }
     60 
     61   void CheckWhite(DataType data_type) {
     62     // Gray pixel should have hue = saturation = 0.0, value = 1.0
     63     AddInputFromArray<T>(TensorShape({3}), {1, 1, 1});
     64     TF_ASSERT_OK(RunOpKernel());
     65 
     66     Tensor expected(allocator(), data_type, TensorShape({3}));
     67     test::FillValues<T>(&expected, {0.0, 0.0, 1.0});
     68     test::ExpectTensorEqual<T>(expected, *GetOutput(0));
     69   }
     70 
     71   void CheckRedMax(DataType data_type) {
     72     // Test case where red channel dominates
     73     AddInputFromArray<T>(TensorShape({3}), {.8f, .4f, .2f});
     74     TF_ASSERT_OK(RunOpKernel());
     75 
     76     T expected_h = 1. / 6. * .2 / .6;
     77     T expected_s = .6 / .8;
     78     T expected_v = .8 / 1.;
     79 
     80     Tensor expected(allocator(), data_type, TensorShape({3}));
     81     test::FillValues<T>(&expected, {expected_h, expected_s, expected_v});
     82     test::ExpectTensorNear<T>(expected, *GetOutput(0), 1e-6);
     83   }
     84 
     85   void CheckGreenMax(DataType data_type) {
     86     // Test case where green channel dominates
     87     AddInputFromArray<T>(TensorShape({3}), {.2f, .8f, .4f});
     88     TF_ASSERT_OK(RunOpKernel());
     89 
     90     T expected_h = 1. / 6. * (2.0 + (.2 / .6));
     91     T expected_s = .6 / .8;
     92     T expected_v = .8 / 1.;
     93 
     94     Tensor expected(allocator(), data_type, TensorShape({3}));
     95     test::FillValues<T>(&expected, {expected_h, expected_s, expected_v});
     96     test::ExpectTensorNear<T>(expected, *GetOutput(0), 1e-6);
     97   }
     98 
     99   void CheckBlueMax(DataType data_type) {
    100     // Test case where blue channel dominates
    101     AddInputFromArray<T>(TensorShape({3}), {.4f, .2f, .8f});
    102     TF_ASSERT_OK(RunOpKernel());
    103 
    104     T expected_h = 1. / 6. * (4.0 + (.2 / .6));
    105     T expected_s = .6 / .8;
    106     T expected_v = .8 / 1.;
    107 
    108     Tensor expected(allocator(), data_type, TensorShape({3}));
    109     test::FillValues<T>(&expected, {expected_h, expected_s, expected_v});
    110     test::ExpectTensorNear<T>(expected, *GetOutput(0), 1e-6);
    111   }
    112 
    113   void CheckNegativeDifference(DataType data_type) {
    114     AddInputFromArray<T>(TensorShape({3}), {0, .1f, .2f});
    115     TF_ASSERT_OK(RunOpKernel());
    116 
    117     T expected_h = 1. / 6. * (4.0 + (-.1 / .2));
    118     T expected_s = .2 / .2;
    119     T expected_v = .2 / 1.;
    120 
    121     Tensor expected(allocator(), data_type, TensorShape({3}));
    122     test::FillValues<T>(&expected, {expected_h, expected_s, expected_v});
    123     test::ExpectTensorNear<T>(expected, *GetOutput(0), 1e-6);
    124   }
    125 };
    126 
    127 template <typename T>
    128 class HSVToRGBOpTest : public OpsTestBase {
    129  protected:
    130   void MakeOp(DataType data_type) {
    131     TF_EXPECT_OK(NodeDefBuilder("hsv_to_rgb_op", "HSVToRGB")
    132                      .Input(FakeInput(data_type))
    133                      .Finalize(node_def()));
    134     TF_EXPECT_OK(InitOp());
    135   }
    136 
    137   void CheckBlack(DataType data_type) {
    138     // Black pixel should map to rgb = [0,0,0]
    139     AddInputFromArray<T>(TensorShape({3}), {0.0, 0.0, 0.0});
    140     TF_ASSERT_OK(RunOpKernel());
    141 
    142     Tensor expected(allocator(), data_type, TensorShape({3}));
    143     test::FillValues<T>(&expected, {0, 0, 0});
    144     test::ExpectTensorEqual<T>(expected, *GetOutput(0));
    145   }
    146 
    147   void CheckGray(DataType data_type) {
    148     // Gray pixel should have hue = saturation = 0.0, value = r/255
    149     AddInputFromArray<T>(TensorShape({3}), {0.0, 0.0, .5});
    150     TF_ASSERT_OK(RunOpKernel());
    151 
    152     Tensor expected(allocator(), data_type, TensorShape({3}));
    153     test::FillValues<T>(&expected, {.5, .5, .5});
    154     test::ExpectTensorEqual<T>(expected, *GetOutput(0));
    155   }
    156 
    157   void CheckWhite(DataType data_type) {
    158     // Gray pixel should have hue = saturation = 0.0, value = 1.0
    159     AddInputFromArray<T>(TensorShape({3}), {0.0, 0.0, 1.0});
    160     TF_ASSERT_OK(RunOpKernel());
    161 
    162     Tensor expected(allocator(), data_type, TensorShape({3}));
    163     test::FillValues<T>(&expected, {1, 1, 1});
    164     test::ExpectTensorEqual<T>(expected, *GetOutput(0));
    165   }
    166 
    167   void CheckRedMax(DataType data_type) {
    168     // Test case where red channel dominates
    169     T expected_h = 1. / 6. * .2 / .6;
    170     T expected_s = .6 / .8;
    171     T expected_v = .8 / 1.;
    172 
    173     AddInputFromArray<T>(TensorShape({3}),
    174                          {expected_h, expected_s, expected_v});
    175     TF_ASSERT_OK(RunOpKernel());
    176 
    177     Tensor expected(allocator(), data_type, TensorShape({3}));
    178     test::FillValues<T>(&expected, {.8, .4, .2});
    179     test::ExpectTensorNear<T>(expected, *GetOutput(0), 1e-6);
    180   }
    181 
    182   void CheckGreenMax(DataType data_type) {
    183     // Test case where green channel dominates
    184     T expected_h = 1. / 6. * (2.0 + (.2 / .6));
    185     T expected_s = .6 / .8;
    186     T expected_v = .8 / 1.;
    187 
    188     AddInputFromArray<T>(TensorShape({3}),
    189                          {expected_h, expected_s, expected_v});
    190     TF_ASSERT_OK(RunOpKernel());
    191 
    192     Tensor expected(allocator(), data_type, TensorShape({3}));
    193     test::FillValues<T>(&expected, {.2, .8, .4});
    194     test::ExpectTensorNear<T>(expected, *GetOutput(0), 1e-6);
    195   }
    196 
    197   void CheckBlueMax(DataType data_type) {
    198     // Test case where blue channel dominates
    199     T expected_h = 1. / 6. * (4.0 + (.2 / .6));
    200     T expected_s = .6 / .8;
    201     T expected_v = .8 / 1.0;
    202 
    203     AddInputFromArray<T>(TensorShape({3}),
    204                          {expected_h, expected_s, expected_v});
    205     TF_ASSERT_OK(RunOpKernel());
    206 
    207     Tensor expected(allocator(), data_type, TensorShape({3}));
    208     test::FillValues<T>(&expected, {.4, .2, .8});
    209     test::ExpectTensorNear<T>(expected, *GetOutput(0), 1e-6);
    210   }
    211 
    212   void CheckNegativeDifference(DataType data_type) {
    213     T expected_h = 1. / 6. * (4.0 + (-.1 / .2));
    214     T expected_s = .2 / .2;
    215     T expected_v = .2 / 1.;
    216 
    217     AddInputFromArray<T>(TensorShape({3}),
    218                          {expected_h, expected_s, expected_v});
    219     TF_ASSERT_OK(RunOpKernel());
    220 
    221     Tensor expected(allocator(), data_type, TensorShape({3}));
    222     test::FillValues<T>(&expected, {0, .1f, .2f});
    223     test::ExpectTensorNear<T>(expected, *GetOutput(0), 1e-6);
    224   }
    225 };
    226 
    227 #define TEST_COLORSPACE(test, dt)         \
    228   TEST_F(test, CheckBlack) {              \
    229     MakeOp(dt);                           \
    230     CheckBlack(dt);                       \
    231   }                                       \
    232   TEST_F(test, CheckGray) {               \
    233     MakeOp(dt);                           \
    234     CheckGray(dt);                        \
    235   }                                       \
    236   TEST_F(test, CheckWhite) {              \
    237     MakeOp(dt);                           \
    238     CheckWhite(dt);                       \
    239   }                                       \
    240   TEST_F(test, CheckRedMax) {             \
    241     MakeOp(dt);                           \
    242     CheckRedMax(dt);                      \
    243   }                                       \
    244   TEST_F(test, CheckGreenMax) {           \
    245     MakeOp(dt);                           \
    246     CheckGreenMax(dt);                    \
    247   }                                       \
    248   TEST_F(test, CheckBlueMax) {            \
    249     MakeOp(dt);                           \
    250     CheckBlueMax(dt);                     \
    251   }                                       \
    252   TEST_F(test, CheckNegativeDifference) { \
    253     MakeOp(dt);                           \
    254     CheckNegativeDifference(dt);          \
    255   }
    256 
    257 typedef RGBToHSVOpTest<float> rgb_to_hsv_float;
    258 typedef RGBToHSVOpTest<double> rgb_to_hsv_double;
    259 
    260 TEST_COLORSPACE(rgb_to_hsv_float, DT_FLOAT);
    261 TEST_COLORSPACE(rgb_to_hsv_double, DT_DOUBLE);
    262 
    263 typedef HSVToRGBOpTest<float> hsv_to_rgb_float;
    264 typedef HSVToRGBOpTest<double> hsv_to_rgb_double;
    265 
    266 TEST_COLORSPACE(hsv_to_rgb_float, DT_FLOAT);
    267 TEST_COLORSPACE(hsv_to_rgb_double, DT_DOUBLE);
    268 }  // namespace tensorflow
    269