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: MakeOp(DataType data_type)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 CheckBlack(DataType data_type)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 CheckGray(DataType data_type)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 CheckWhite(DataType data_type)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 CheckRedMax(DataType data_type)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 CheckGreenMax(DataType data_type)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 CheckBlueMax(DataType data_type)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 CheckNegativeDifference(DataType data_type)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: MakeOp(DataType data_type)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 CheckBlack(DataType data_type)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 CheckGray(DataType data_type)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 CheckWhite(DataType data_type)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 CheckRedMax(DataType data_type)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 CheckGreenMax(DataType data_type)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 CheckBlueMax(DataType data_type)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 CheckNegativeDifference(DataType data_type)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