
    2VhI:                     x    d dl mZ d dlmZ d dlmZ d dlmZ d dlmZ d dl	m
Z
  ed       G d d	e             Zy
)    )keras_export)BaseImagePreprocessingLayer)clip_to_image_size)convert_format)SeedGenerator)backend_utilszkeras.layers.RandomTranslationc                        e Zd ZdZdZdZdZdZ	 	 	 	 	 d fd	Zd Z	d Z
dd	Zdd
Zd Zd Z	 ddZ	 ddZddZd Zd Zd Z fdZ xZS )RandomTranslationa  A preprocessing layer which randomly translates images during training.

    This layer will apply random translations to each image during training,
    filling empty space according to `fill_mode`.

    Input pixel values can be of any range (e.g. `[0., 1.)` or `[0, 255]`) and
    of integer or floating point dtype. By default, the layer will output
    floats.

    Input shape:
        3D (unbatched) or 4D (batched) tensor with shape:
        `(..., height, width, channels)`, in `"channels_last"` format,
        or `(..., channels, height, width)`, in `"channels_first"` format.

    Output shape:
        3D (unbatched) or 4D (batched) tensor with shape:
        `(..., target_height, target_width, channels)`,
        or `(..., channels, target_height, target_width)`,
        in `"channels_first"` format.

    **Note:** This layer is safe to use inside a `tf.data` pipeline
    (independently of which backend you're using).

    Args:
        height_factor: a float represented as fraction of value, or a tuple of
            size 2 representing lower and upper bound for shifting vertically. A
            negative value means shifting image up, while a positive value means
            shifting image down. When represented as a single positive float,
            this value is used for both the upper and lower bound. For instance,
            `height_factor=(-0.2, 0.3)` results in an output shifted by a random
            amount in the range `[-20%, +30%]`. `height_factor=0.2` results in
            an output height shifted by a random amount in the range
            `[-20%, +20%]`.
        width_factor: a float represented as fraction of value, or a tuple of
            size 2 representing lower and upper bound for shifting horizontally.
            A negative value means shifting image left, while a positive value
            means shifting image right. When represented as a single positive
            float, this value is used for both the upper and lower bound. For
            instance, `width_factor=(-0.2, 0.3)` results in an output shifted
            left by 20%, and shifted right by 30%. `width_factor=0.2` results
            in an output height shifted left or right by 20%.
        fill_mode: Points outside the boundaries of the input are filled
            according to the given mode. Available methods are `"constant"`,
            `"nearest"`, `"wrap"` and `"reflect"`. Defaults to `"constant"`.
            - `"reflect"`: `(d c b a | a b c d | d c b a)`
                The input is extended by reflecting about the edge of the last
                pixel.
            - `"constant"`: `(k k k k | a b c d | k k k k)`
                The input is extended by filling all values beyond
                the edge with the same constant value k specified by
                `fill_value`.
            - `"wrap"`: `(a b c d | a b c d | a b c d)`
                The input is extended by wrapping around to the opposite edge.
            - `"nearest"`: `(a a a a | a b c d | d d d d)`
                The input is extended by the nearest pixel.
            Note that when using torch backend, `"reflect"` is redirected to
            `"mirror"` `(c d c b | a b c d | c b a b)` because torch does not
            support `"reflect"`.
            Note that torch backend does not support `"wrap"`.
        interpolation: Interpolation mode. Supported values: `"nearest"`,
            `"bilinear"`.
        seed: Integer. Used to create a random seed.
        fill_value: a float represents the value to be filled outside the
            boundaries when `fill_mode="constant"`.
        data_format: string, either `"channels_last"` or `"channels_first"`.
            The ordering of the dimensions in the inputs. `"channels_last"`
            corresponds to inputs with shape `(batch, height, width, channels)`
            while `"channels_first"` corresponds to inputs with shape
            `(batch, channels, height, width)`. It defaults to the
            `image_data_format` value found in your Keras config file at
            `~/.keras/keras.json`. If you never set it, then it will be
            `"channels_last"`.
        **kwargs: Base layer keyword arguments, such as `name` and `dtype`.
    Fz^The `factor` argument should be a number (or a list of two numbers) in the range [-1.0, 1.0]. )reflectwrapconstantnearest)r   bilinearc                    t        	|   d	d|i| || _        | j                  |d      \  | _        | _        || _        | j                  |d      \  | _        | _        || j                  vrt        d| d| j                   d      || j                  vrt        d| d| j                   d      || _        || _        || _        || _        t!        |      | _        d| _        y )
Ndata_formatheight_factorwidth_factorzUnknown `fill_mode` z. Expected of one .zUnknown `interpolation` F )super__init__r   _set_factorheight_lowerheight_upperr   width_lowerwidth_upper_SUPPORTED_FILL_MODENotImplementedError_SUPPORTED_INTERPOLATION	fill_mode
fill_valueinterpolationseedr   	generatorsupports_jit)
selfr   r   r    r"   r#   r!   r   kwargs	__class__s
            u/home/dcms/DCMS/lib/python3.12/site-packages/keras/src/layers/preprocessing/image_preprocessing/random_translation.pyr   zRandomTranslation.__init__d   s    	;[;F;*/3/?/??0
,4, )-1-=-=..
*$* D555%&yk1C,,-Q0   = ==%*=/9K0014 
 #$*	&t,!    c                    t        |t        t        f      rft        |      dk7  rt	        | j
                  d| d| z         | j                  |d          | j                  |d          t        |      \  }}||fS t        |t        t        f      r(| j                  |       t        |      }| |g\  }}||fS t	        | j
                  d| d| z         )N   z
Received: =r      )
isinstancetuplelistlen
ValueError_FACTOR_VALIDATION_ERROR_check_factor_rangesortedintfloatabs)r&   factorfactor_nameloweruppers        r)   r   zRandomTranslation._set_factor   s    fudm,6{a 11";-q9:  $$VAY/$$VAY/!&>LE5 e| e-$$V,[F#GV,LE5 e|	 --{m1VH56 r*   c                 N    |dkD  s|dk  rt        | j                  d| z         y )Ng      ?g      zReceived: input_number=)r3   r4   )r&   input_numbers     r)   r5   z%RandomTranslation._check_factor_range   s;    #!4--+L>:;  "5r*   c                 z    | j                   j                  || j                        }|r| j                  ||      S |S N)backendcastcompute_dtype_translate_inputs)r&   imagestransformationtrainings       r)   transform_imagesz"RandomTranslation.transform_images   s9    ""64+=+=>))&.AAr*   c                     |S rA   r   )r&   labelsrG   rH   s       r)   transform_labelsz"RandomTranslation.transform_labels   s    r*   c                     | j                   j                  j                  |dd      \  }}}}}}	}
}|
|z  ||z  z   dz   }||z  ||z  z   |z   |z  }||z  ||z  z   |	z   |z  }||fS )N   axisr.   )rB   numpysplit)r&   xy	transforma0a1a2b0b1b2c0c1kx_transformedy_transformeds                  r)   get_transformed_x_yz%RandomTranslation.get_transformed_x_y   s    )-););)A)Aqr *B *
&BBBB FR!VOaa"q&2-2a"q&2-2m++r*   c                 B   |d   }| j                   j                  j                  |dd      \  }}}}| j                   j                  ||j                        }| j                   j                  ||j                        }t        |j                        dk(  rL| j                   j                  j                  |d      }| j                   j                  j                  |d      }| j                   j                  j                  ||z
  ||z
  ||z
  ||z
  gd      |d<   |S )Nboxes   rO   rP   dtype   )	rB   rR   rS   convert_to_tensorrg   r2   shapeexpand_dimsconcatenate)	r&   bounding_boxesw_shift_factorh_shift_factorbboxesx1x2x3x4s	            r)   get_shifted_bboxz"RandomTranslation.get_shifted_bbox   s   (++11&!"1EBB77"(( 8 
 77"(( 8 
 v||!!\\//;;NBON!\\//;;NBON"&,,"4"4"@"@^#^#^#^#	  #A #
w r*   c                    |rt        j                         r| j                  j                  d       | j                  dk(  rd}d}nd}d}|d   |   |d   |   }}t        || j                  d||      }|d	   }| j                  |      }	| j                  d
d
|	      \  }
}| j                  ||
|      }t        |||d      }t        |d| j                  ||      }| j                  j                          |S )N
tensorflowchannels_firstrO   input_shapexyxy)sourcetargetheightwidthtranslationsr   )rm   r   r   bounding_box_format)r   in_tf_graphrB   set_backendr   r   r   _get_translation_matrixrb   ru   r   reset)r&   rm   rG   rH   height_axis
width_axisinput_heightinput_widthr   rV   rn   ro   s               r)   transform_bounding_boxesz*RandomTranslation.transform_bounding_boxes   s.    ((*((6#33 
 
 }-k:}-j9 &L
 ,//#!N *.9L44\BI-1-E-E1i.*NN "22N 0-#!$*	N ,//#!N LL r*   c                 *    | j                  |||      S )N)rH   )rI   )r&   segmentation_masksrG   rH   s       r)   transform_segmentation_masksz.RandomTranslation.transform_segmentation_masks  s#     $$ % 
 	
r*   c                    |sy t        |t              r|d   }n|}| j                  j                  |      }t	        |      dk(  }|r| j                  j                  |      }d}n|d   }| j
                  dk(  r|d   }|d   }	n
|d   }|d   }	|%| j                  | j                  j                        }| j                  j                  j                  | j                  | j                  |dg|	      }
| j                  j                  j                  |
|      }
| j                  j                  j                  | j                  | j                  |dg|	      }| j                  j                  j                  ||	      }| j                  j!                  | j                  j                  j#                  ||
gd
      d      }||dS )NrF   rh   r.   r   rx   ry   rO   rz   )minvalmaxvalrj   r#   rP   float32rf   )r   r{   )r/   dictrB   rj   r2   r   _get_seed_generator_backendrandomuniformr   r   rR   multiplyr   r   rC   rl   )r&   datarH   r#   rF   images_shape	unbatched
batch_sizer   r   height_translatewidth_translater   s                r)   get_random_transformationz+RandomTranslation.get_random_transformation  s   dD!(^FF||))&1%*	<<--f5LJ%aJ//!"%F $E!"%F $E<++DLL,A,ABD<<..66$$$$q/	 7 
  <<--667GP,,--55####q/	 6 
 ,,,,55ouM||((LL** "23! +  	 ) 
 !-\JJr*   c                    ||S | j                   j                  |      }t        |      dk(  }|r'| j                   j                  j	                  |d      }|d   }| j                   j
                  j                  || j                  |      | j                  | j                  | j                  | j                        }|r'| j                   j                  j                  |d      }|S )Nrh   r   rP   r   )rV   r"   r    r!   r   )rB   rj   r2   rR   rk   imageaffine_transformr   r"   r    r!   r   squeeze)r&   inputsrG   inputs_shaper   r   outputss          r)   rE   z#RandomTranslation._translate_inputsF  s    !M||))&1%*	\\''33F3CF%n5,,$$5522<@,,nn(( 6 
 ll((00q0AGr*   c                 4   | j                   j                  |      d   }| j                   j                  j                  | j                   j                  j	                  |df      | j                   j                  j                  |df      |d d ddf    | j                   j                  j                  |df      | j                   j                  j	                  |df      |d d dd f    | j                   j                  j                  |df      gd      S )Nr   r.   r,   rP   )rB   rj   rR   rl   oneszeros)r&   r   num_translationss      r)   r   z)RandomTranslation._get_translation_matrix]  s   <<--l;A> ||!!--""'')91(=>""((*:A)>?a1f%%""((*:A)>?""'')91(=>ae$$""((*:A)>?  . 
 	
r*   c                     |S rA   r   )r&   r{   s     r)   compute_output_shapez&RandomTranslation.compute_output_shaper  s    r*   c                     t         |          }| j                  | j                  | j                  | j
                  | j                  | j                  | j                  d}i ||S )N)r   r   r    r"   r#   r!   r   )	r   
get_configr   r   r    r"   r#   r!   r   )r&   base_configconfigr(   s      r)   r   zRandomTranslation.get_configu  sb    g(*!// --!//II//++
 )+(((r*   )r   r   Ng        N)T)TN)__name__
__module____qualname____doc___USE_BASE_FACTORr4   r   r   r   r   r5   rI   rL   rb   ru   r   r   r   rE   r   r   r   __classcell__)r(   s   @r)   r
   r
      s    IV 	%  F6  %"N*,< 	9x <@
.K`.
*) )r*   r
   N)keras.src.api_exportr   Qkeras.src.layers.preprocessing.image_preprocessing.base_image_preprocessing_layerr   Lkeras.src.layers.preprocessing.image_preprocessing.bounding_boxes.convertersr   r   keras.src.random.seed_generatorr   keras.src.utilsr   r
   r   r*   r)   <module>r      sD    - : ) ./p)3 p) 0p)r*   