Home | History | Annotate | Download | only in ops
      1 # Copyright 2017 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 """Python layer for distort_image_ops."""
     16 from __future__ import absolute_import
     17 from __future__ import division
     18 from __future__ import print_function
     19 
     20 from tensorflow.contrib.image.ops import gen_distort_image_ops
     21 from tensorflow.contrib.util import loader
     22 from tensorflow.python.framework import dtypes
     23 from tensorflow.python.framework import ops
     24 from tensorflow.python.ops import image_ops
     25 from tensorflow.python.ops import random_ops
     26 from tensorflow.python.platform import resource_loader
     27 
     28 _distort_image_ops = loader.load_op_library(
     29     resource_loader.get_path_to_datafile('_distort_image_ops.so'))
     30 
     31 
     32 # pylint: disable=invalid-name
     33 def random_hsv_in_yiq(image,
     34                       max_delta_hue=0,
     35                       lower_saturation=1,
     36                       upper_saturation=1,
     37                       lower_value=1,
     38                       upper_value=1,
     39                       seed=None):
     40   """Adjust hue, saturation, value of an RGB image randomly in YIQ color space.
     41 
     42   Equivalent to `adjust_yiq_hsv()` but uses a `delta_h` randomly
     43   picked in the interval `[-max_delta_hue, max_delta_hue]`, a `scale_saturation`
     44   randomly picked in the interval `[lower_saturation, upper_saturation]`, and
     45   a `scale_value` randomly picked in the interval
     46   `[lower_saturation, upper_saturation]`.
     47 
     48   Args:
     49     image: RGB image or images. Size of the last dimension must be 3.
     50     max_delta_hue: float. Maximum value for the random delta_hue. Passing 0
     51                    disables adjusting hue.
     52     lower_saturation: float.  Lower bound for the random scale_saturation.
     53     upper_saturation: float.  Upper bound for the random scale_saturation.
     54     lower_value: float.  Lower bound for the random scale_value.
     55     upper_value: float.  Upper bound for the random scale_value.
     56     seed: An operation-specific seed. It will be used in conjunction
     57       with the graph-level seed to determine the real seeds that will be
     58       used in this operation. Please see the documentation of
     59       set_random_seed for its interaction with the graph-level random seed.
     60 
     61   Returns:
     62     3-D float tensor of shape `[height, width, channels]`.
     63 
     64   Raises:
     65     ValueError: if `max_delta`, `lower_saturation`, `upper_saturation`,
     66                `lower_value`, or `upper_Value` is invalid.
     67   """
     68   if max_delta_hue < 0:
     69     raise ValueError('max_delta must be non-negative.')
     70 
     71   if lower_saturation < 0:
     72     raise ValueError('lower_saturation must be non-negative.')
     73 
     74   if lower_value < 0:
     75     raise ValueError('lower_value must be non-negative.')
     76 
     77   if lower_saturation > upper_saturation:
     78     raise ValueError('lower_saturation must be < upper_saturation.')
     79 
     80   if lower_value > upper_value:
     81     raise ValueError('lower_value must be < upper_value.')
     82 
     83   if max_delta_hue == 0:
     84     delta_hue = 0
     85   else:
     86     delta_hue = random_ops.random_uniform(
     87         [], -max_delta_hue, max_delta_hue, seed=seed)
     88   if lower_saturation == upper_saturation:
     89     scale_saturation = lower_saturation
     90   else:
     91     scale_saturation = random_ops.random_uniform(
     92         [], lower_saturation, upper_saturation, seed=seed)
     93   if lower_value == upper_value:
     94     scale_value = lower_value
     95   else:
     96     scale_value = random_ops.random_uniform(
     97         [], lower_value, upper_value, seed=seed)
     98   return adjust_hsv_in_yiq(image, delta_hue, scale_saturation, scale_value)
     99 
    100 
    101 def adjust_hsv_in_yiq(image,
    102                       delta_hue=0,
    103                       scale_saturation=1,
    104                       scale_value=1,
    105                       name=None):
    106   """Adjust hue, saturation, value of an RGB image in YIQ color space.
    107 
    108   This is a convenience method that converts an RGB image to float
    109   representation, converts it to YIQ, rotates the color around the Y channel by
    110   delta_hue in radians, scales the chrominance channels (I, Q) by
    111   scale_saturation, scales all channels (Y, I, Q) by scale_value,
    112   converts back to RGB, and then back to the original data type.
    113 
    114   `image` is an RGB image.  The image hue is adjusted by converting the
    115   image to YIQ, rotating around the luminance channel (Y) by
    116   `delta_hue` in radians, multiplying the chrominance channels (I, Q)  by
    117   `scale_saturation`, and multiplying all channels (Y, I, Q)  by
    118   `scale_value`.  The image is then converted back to RGB.
    119 
    120   Args:
    121     image: RGB image or images. Size of the last dimension must be 3.
    122     delta_hue: float, the hue rotation amount, in radians.
    123     scale_saturation: float, factor to multiply the saturation by.
    124     scale_value: float, factor to multiply the value by.
    125     name: A name for this operation (optional).
    126 
    127   Returns:
    128     Adjusted image(s), same shape and DType as `image`.
    129   """
    130   with ops.name_scope(name, 'adjust_hsv_in_yiq', [image]) as name:
    131     image = ops.convert_to_tensor(image, name='image')
    132     # Remember original dtype to so we can convert back if needed
    133     orig_dtype = image.dtype
    134     flt_image = image_ops.convert_image_dtype(image, dtypes.float32)
    135 
    136     rgb_altered = gen_distort_image_ops.adjust_hsv_in_yiq(
    137         flt_image, delta_hue, scale_saturation, scale_value)
    138 
    139     return image_ops.convert_image_dtype(rgb_altered, orig_dtype)
    140