• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2 Licensed under the Apache License, Version 2.0 (the "License");
3 you may not use this file except in compliance with the License.
4 You may obtain a copy of the License at
5 
6     http://www.apache.org/licenses/LICENSE-2.0
7 
8 Unless required by applicable law or agreed to in writing, software
9 distributed under the License is distributed on an "AS IS" BASIS,
10 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 See the License for the specific language governing permissions and
12 limitations under the License.
13 ==============================================================================*/
14 #ifndef TENSORFLOW_CONTRIB_IMAGE_KERNELS_ADJUST_HSV_IN_YIQ_OP_H_
15 #define TENSORFLOW_CONTRIB_IMAGE_KERNELS_ADJUST_HSV_IN_YIQ_OP_H_
16 
17 #if GOOGLE_CUDA
18 #define EIGEN_USE_GPU
19 #endif  // GOOGLE_CUDA
20 
21 #include <cmath>
22 #include "third_party/eigen3/Eigen/Core"
23 #include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor"
24 
25 #include "tensorflow/core/framework/op_kernel.h"
26 #include "tensorflow/core/framework/register_types.h"
27 #include "tensorflow/core/framework/types.h"
28 
29 namespace tensorflow {
30 
31 static constexpr int kChannelSize = 3;
32 
33 namespace internal {
34 
35 template <int MATRIX_SIZE>
compute_tranformation_matrix(const float delta_h,const float scale_s,const float scale_v,float * matrix)36 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void compute_tranformation_matrix(
37     const float delta_h, const float scale_s, const float scale_v,
38     float* matrix) {
39   static_assert(MATRIX_SIZE == kChannelSize * kChannelSize,
40                 "Size of matrix should be 9.");
41   // Projection matrix from RGB to YIQ. Numbers from wikipedia
42   // https://en.wikipedia.org/wiki/YIQ
43   Eigen::Matrix3f yiq;
44   /* clang-format off */
45   yiq << 0.299, 0.587, 0.114,
46          0.596, -0.274, -0.322,
47          0.211, -0.523, 0.312;
48   Eigen::Matrix3f yiq_inverse;
49   yiq_inverse << 1, 0.95617069, 0.62143257,
50                  1, -0.2726886, -0.64681324,
51                  1, -1.103744, 1.70062309;
52   /* clang-format on */
53   // Construct hsv linear transformation matrix in YIQ space.
54   // https://beesbuzz.biz/code/hsv_color_transforms.php
55   float vsu = scale_v * scale_s * std::cos(delta_h);
56   float vsw = scale_v * scale_s * std::sin(delta_h);
57   Eigen::Matrix3f hsv_transform;
58   /* clang-format off */
59   hsv_transform << scale_v, 0, 0,
60                    0, vsu, -vsw,
61                    0, vsw, vsu;
62   /* clang-format on */
63   // Compute final transformation matrix = inverse_yiq * hsv_transform * yiq
64   Eigen::Map<Eigen::Matrix<float, 3, 3, Eigen::ColMajor>> eigen_matrix(matrix);
65   eigen_matrix = yiq_inverse * hsv_transform * yiq;
66 }
67 }  // namespace internal
68 
69 #if GOOGLE_CUDA
70 typedef Eigen::GpuDevice GPUDevice;
71 
72 namespace functor {
73 
74 struct AdjustHsvInYiqGPU {
75   void operator()(OpKernelContext* ctx, int channel_count,
76                   const Tensor* const input, const float* const delta_h,
77                   const float* const scale_s, const float* const scale_v,
78                   Tensor* const output);
79 };
80 
81 }  // namespace functor
82 
83 #endif  // GOOGLE_CUDA
84 
85 }  // namespace tensorflow
86 
87 #endif  // TENSORFLOW_CONTRIB_IMAGE_KERNELS_ADJUST_HSV_IN_YIQ_OP_H_
88