1/* Copyright 2015 The TensorFlow Authors. All Rights Reserved. 2 3Licensed under the Apache License, Version 2.0 (the "License"); 4you may not use this file except in compliance with the License. 5You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9Unless required by applicable law or agreed to in writing, software 10distributed under the License is distributed on an "AS IS" BASIS, 11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12See the License for the specific language governing permissions and 13limitations 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 29namespace tensorflow { 30 31template <typename T> 32class 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 127template <typename T> 128class 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 257typedef RGBToHSVOpTest<float> rgb_to_hsv_float; 258typedef RGBToHSVOpTest<double> rgb_to_hsv_double; 259 260TEST_COLORSPACE(rgb_to_hsv_float, DT_FLOAT); 261TEST_COLORSPACE(rgb_to_hsv_double, DT_DOUBLE); 262 263typedef HSVToRGBOpTest<float> hsv_to_rgb_float; 264typedef HSVToRGBOpTest<double> hsv_to_rgb_double; 265 266TEST_COLORSPACE(hsv_to_rgb_float, DT_FLOAT); 267TEST_COLORSPACE(hsv_to_rgb_double, DT_DOUBLE); 268} // namespace tensorflow 269