
    2Vh%                     `    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)
converters)SeedGeneratorzkeras.layers.RandomRotationc                   r     e Zd ZdZdZdZ	 	 	 	 	 d fd	ZddZddZ	 ddZ		 ddZ
dd	Zd
 Z fdZ xZS )RandomRotationa  A preprocessing layer which randomly rotates images during training.

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

    By default, random rotations are only applied during training.
    At inference time, the layer does nothing. If you need to apply random
    rotations at inference time, pass `training=True` when calling the layer.

    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.

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

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

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

    Args:
        factor: a float represented as fraction of 2 Pi, or a tuple of size 2
            representing lower and upper bound for rotating clockwise and
            counter-clockwise. A positive values means rotating
            counter clock-wise,
            while a negative value means clock-wise.
            When represented as a single
            float, this value is used for both the upper and lower bound.
            For instance, `factor=(-0.2, 0.3)`
            results in an output rotation by a random
            amount in the range `[-20% * 360, 30% * 360]`.
            `factor=0.2` results in an
            output rotating by a random amount
            in the range `[-20% * 360, 20% * 360]`.
        fill_mode: Points outside the boundaries of the input are filled
            according to the given mode
            (one of `{"constant", "reflect", "wrap", "nearest"}`).
            - *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 = 0.
            - *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.
        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"`.
    )reflectwrapconstantnearest)r   bilinearc                 `   t        |   d||d| || _        t        |      | _        || _        || _        || _        d| _        | j
                  | j                  vrt        d| d| j                   d      | j                  | j                  vrt        d| d| j                   d      y )N)factordata_formatFzUnknown `fill_mode` z. Expected of one .zUnknown `interpolation`  )super__init__seedr   	generator	fill_modeinterpolation
fill_valuesupports_jit_SUPPORTED_FILL_MODENotImplementedError_SUPPORTED_INTERPOLATION)	selfr   r   r   r   r   r   kwargs	__class__s	           r/home/dcms/DCMS/lib/python3.12/site-packages/keras/src/layers/preprocessing/image_preprocessing/random_rotation.pyr   zRandomRotation.__init__S   s     	JKJ6J	&t,"*$!>>!:!::%&yk1C,,-Q0  T%B%BB%*=/9K0014  C    c                    | j                   j                  || j                        }|rV| j                   j                  j	                  ||d   | j
                  | j                  | j                  | j                        S |S )Nrotation_matrix)images	transformr   r   r   r   )	backendcastcompute_dtypeimageaffine_transformr   r   r   r   )r   r%   transformationtrainings       r!   transform_imageszRandomRotation.transform_imagesp   sv    ""64+=+=><<%%66():;"00..?? ,, 7   r"   c                     |S Nr   )r   labelsr,   r-   s       r!   transform_labelszRandomRotation.transform_labels}   s    r"   c                    |r| j                   }|d   }|d   }|d   }|d   }t        j                  ||d   |j                  j	                  |g      |j                  j	                  |g      |j                  j                  |g      |j                  j	                  |g      |j                  j	                  |g      ||	      }||d<   t        j                  |||d      }t        j                  |d| j                  ||	      }|S )
Nboxesimage_heightimage_width
batch_sizeangle)	r4   r8   translate_xtranslate_yscaleshear_xshear_yheightwidthxyxy)r>   r?   bounding_box_format)sourcetargetr>   r?   )	r'   r   r+   numpyzerosonesclip_to_image_sizeconvert_formatrA   )	r   bounding_boxesr,   r-   opsr4   r>   r?   r7   s	            r!   transform_bounding_boxesz'RandomRotation.transform_bounding_boxes   s
    ,,C"7+E#N3F"=1E'5J//$W-IIOOZL9IIOOZL9iinnj\2		5		5
E ',N7#'::$*	N (66//N r"   c                 *    | j                  |||      S )N)r-   )r.   )r   segmentation_masksr,   r-   s       r!   transform_segmentation_masksz+RandomRotation.transform_segmentation_masks   s#     $$ % 
 	
r"   c                    | j                   }|sy t        |t              r|d   }n|}|j                  j	                  |      }t        |      dk(  r*|d   }| j                  dk(  r|d   }|d   }	n1|d   }|d   }	n&d}| j                  dk(  r|d   }|d   }	n
|d   }|d   }	|| j                  |j                        }| j                  d   dz  }
| j                  d   dz  }|j                  j                  |f|
||	      }d
\  }}| j                  ||||j                  j                  |g      |j                  j                  |g      |j                  j                  |g      |j                  j                  |g      |j                  j                  |g      ||	
      }t        |      dk(  r'| j                   j                  j!                  |d      }||||	|dS )Nr%      r   channels_last         g     v@)shapeminvalmaxvalr   )      ?rX   )
center_xcenter_yr8   r9   r:   r;   r<   r=   r>   r?   )axis)r8   r$   r5   r6   r7   )r'   
isinstancedictcorerU   lenr   _get_seed_generator_backendr   randomuniform_compute_affine_matrixrD   rE   rF   squeeze)r   datar-   r   rJ   r%   rU   r7   r5   r6   lowerupperr8   rY   rZ   r$   s                   r!   get_random_transformationz(RandomRotation.get_random_transformation   s   lldD!(^FFv&u:?qJ?2$Qx#Ah$Qx#AhJ?2$Qx#Ah$Qx#Ah<++CLL9DA&A&

""-	 # 
 &(55		5		5))..*.IIOOZL1IIOOZL1 6 
 u:?"ll0088a 9 O .(&$
 	
r"   c                     |S r0   r   )r   input_shapes     r!   compute_output_shapez#RandomRotation.compute_output_shape   s    r"   c                     | j                   | j                  | j                  | j                  | j                  | j
                  d}t        |          }i ||S )N)r   r   r   r   r   r   )r   r   r   r   r   r   r   
get_config)r   configbase_configr    s      r!   rn   zRandomRotation.get_config   sW    kk++//!//II
 g(*(+(((r"   )r	   r   Ng        N)T)TN)__name__
__module____qualname____doc__r   r   r   r.   r2   rK   rN   ri   rl   rn   __classcell__)r    s   @r!   r   r      sd    AF F6
  : 	&R <@
;
z
) 
)r"   r   N)	keras.src.api_exportr   Qkeras.src.layers.preprocessing.image_preprocessing.base_image_preprocessing_layerr   Akeras.src.layers.preprocessing.image_preprocessing.bounding_boxesr   keras.src.random.seed_generatorr   r   r   r"   r!   <module>rz      s<    - : +,m)0 m) -m)r"   