
    2Vh^+                     T    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)SeedGeneratorzkeras.layers.RandomErasingc                        e Zd ZdZdZdZ	 	 	 	 	 	 d fd	Zd Zd Zd Z	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 )RandomErasinga  Random Erasing data augmentation technique.

    Random Erasing is a data augmentation method where random patches of
    an image are erased (replaced by a constant value or noise)
    during training to improve generalization.

    Args:
        factor: A single float or a tuple of two floats.
            `factor` controls the probability of applying the transformation.
            - `factor=0.0` ensures no erasing is applied.
            - `factor=1.0` means erasing is always applied.
            - If a tuple `(min, max)` is provided, a probability value
              is sampled between `min` and `max` for each image.
            - If a single float is provided, a probability is sampled
              between `0.0` and the given float.
            Default is 1.0.
        scale: A tuple of two floats representing the aspect ratio range of
            the erased patch. This defines the width-to-height ratio of
            the patch to be erased. It can help control the rw shape of
            the erased region. Default is (0.02, 0.33).
        fill_value: A value to fill the erased region with. This can be set to
            a constant value or `None` to sample a random value
            from a normal distribution. Default is `None`.
        value_range: the range of values the incoming images will have.
            Represented as a two-number tuple written `[low, high]`. This is
            typically either `[0, 1]` or `[0, 255]` depending on how your
            preprocessing pipeline is set up.
        seed: Integer. Used to create a random seed.

    References:
       - [Random Erasing paper](https://arxiv.org/abs/1708.04896).
    F)r      c                 6   t        |   dd|i| | j                  |       | j                  |d      | _        || _        || _        || _        t        |      | _	        | j                  dk(  rd| _        d| _        d| _        y d| _        d| _        d| _        y )Ndata_formatscalechannels_first )super__init___set_factor_set_factor_by_namer   
fill_valuevalue_rangeseedr   	generatorr
   height_axis
width_axischannel_axis)	selffactorr   r   r   r   r
   kwargs	__class__s	           q/home/dcms/DCMS/lib/python3.12/site-packages/keras/src/layers/preprocessing/image_preprocessing/random_erasing.pyr   zRandomErasing.__init__.   s     	;[;F; --eW=
$&	&t,//!D DO "D!D DO "D    c                 :   d| d| j                   d    d| j                   d    d| }t        |t        t        f      r`t	        |      dk7  rt        |      |d   | j                   d   kD  s|d   | j                   d   k  rt        |      t        |      \  }}||fS t        |t        t        f      r]|| j                   d   k  s|| j                   d   kD  rt        |      t        |      }t        | | j                   d         |g\  }}||fS t        |      )NzThe `zG` argument should be a number (or a list of two numbers) in the range [r   z, r   z]. Received: factor=   )_FACTOR_BOUNDS
isinstancetuplelistlen
ValueErrorsortedintfloatabsmax)r   r   name	error_msgloweruppers         r    r   z!RandomErasing._set_factor_by_nameI   sF   D6  ##A&'r$*=*=a*@)A B  &x	) 	 fudm,6{a ++q	D//22!9t22155 ++!&>LE5 e| e-,,Q//D//22 ++[F)<)<Q)?@&ILE5 e| Y''r!   c                     | j                   j                  ||z  | j                        }| j                   j                  j	                  |gdd| j                  |      ||z
  z  }||z   }||fS )Ndtyper   r   shapeminvalmaxvalr5   r   )backendcastcompute_dtyperandomuniform)r   
batch_sizeimage_length
crop_ratior   crop_length	start_posend_poss           r    _compute_crop_boundsz"RandomErasing._compute_crop_boundsf   s    ll''%T-?-? ( 
 LL''//,$$ 0 
 K')	 k)'!!r!   c                 x     fd}| j                      | j                     }} |||      \  }}|\  }}	}
}|d d d d d f   }|
d d d d d f   }
|	d d d d d f   }	|d d d d d f   }||k\  ||	k  z  ||
k\  z  ||k  z  } j                  j                  j	                  || j
                      j
                        }|S )Nc                    j                   j                  j                  j                   j                  j                  | j                        j                   j                  j                  |j                        d      \  }}j
                  dk(  rhj                   j                  |d d d d d d f   j                        }j                   j                  |d d d d d d f   j                        }||fS j                   j                  |d d d d d d f   j                        }j                   j                  |d d d d d d f   j                        }||fS )Nr4   ij)indexingchannels_last)r:   numpymeshgridaranger<   r
   r;   )image_heightimage_widthgrid_ygrid_xr   s       r    _generate_grid_xyz=RandomErasing._generate_batch_mask.<locals>._generate_grid_xyx   ss   !\\//88"")) (:(: *  ""))t'9'9 *   9 NFF ?2**4At+,D4F4F +  **4At+,D4F4F +  6>! **4q!+,D4F4F +  **4q!+,D4F4F +  6>!r!   )axis)r   r   r:   rK   repeatr   )r   images_shapebox_cornersrR   rN   rO   rQ   rP   x0x1y0y1batch_maskss   `            r    _generate_batch_maskz"RandomErasing._generate_batch_maskw   s    	"6 ))*) " +<E$BB4t#$4t#$4t#$4t#$ r\frk*fl;v{K 	 ll((//d&7&78t?P?P 0 
 r!   c                    | j                   }|C| j                  j                  j                  || j                  |      | j
                  d   z  }nd}t        |t        t        f      rLt        |      dk7  rt        |      | j                  j                  j                  ||| j                        }nVt        |t        t        f      r5| j                  j                  j                  || j                        |z  }nt        |      | j                  j                  j!                  || j
                  d   | j
                  d         }|S )N)r5   r   r   zJThe `fill_value` argument should be a number (or a list of three numbers)    r4   r   )r   r:   r=   normalr<   r   r%   r&   r'   r(   r)   rK   	full_liker+   r,   onesclip)r   imagesrU   r   r   r0   s         r    _get_fill_valuezRandomErasing._get_fill_value   sG   __
##** ,, + 
 ""1%& 0  *udm4z?a'$Y//!\\//99Jd.@.@ : 
 Je5LL&&++$D,>,> ,  !!  !++\\'',,((+T-=-=a-@

 r!   c                    |sy t        |t              r|d   }n|}| j                  j                  |      }t	        |      }|dk(  rd}n|dk(  r|d   }nt        d|       || j                     }|| j                     }	|xs% | j                  | j                  j                        }| j                  j                  j                  |df| j                  d   | j                  d   | j                  |      }
| j                  j                  j                  |
      }
| j!                  ||	|
d d df   |      \  }}| j!                  |||
d d df   |      \  }}| j#                  |||||f      }| j                  j                  j                  |f| j$                  d   | j$                  d   |	      }| j                  j                  j                  |fd
d|	      }||k  }| j'                  |||      }|||dS )Nrc   r^   r      r   zBExpected the input image to be rank 3 or 4. Received inputs.shape=r#   r6   )r7   r8   r9   r   g              ?)apply_erasingr[   r   )r%   dictr:   r7   r(   r)   r   r   _get_seed_generator_backendr=   r>   r   r<   rK   sqrtrE   r\   r   rd   )r   datatrainingr   rc   rU   rankr?   rN   rO   
mix_weightrW   rX   rY   rZ   r[   erase_probabilityrandom_thresholdrh   r   s                       r    get_random_transformationz'RandomErasing.get_random_transformation   s.   dD!(^FF||))&1< 19JQY%aJ  ,~/ 
 $D$4$45"4??3Ft//0E0EF\\((00q/::a=::a=$$ 1 

 \\'',,Z8
**Z1%5t
B **jA&6
B //R

 !LL//77-;;q>;;q>	 8 
  <<..66-	 7 
 )+<<))&,E
 +&$
 	
r!   c                 n   |r| j                   j                  || j                        }|d   }|d   }|d   }| j                   j                  j	                  |||      }| j                   j                  j	                  |d d d d d f   ||      }| j                   j                  || j                        }|S )Nr[   rh   r   )r:   r;   r<   rK   where)r   rc   transformationrn   r[   rh   r   erased_imagess           r    transform_imageszRandomErasing.transform_images  s    \\&&vt/A/ABF(7K*?;M'5J LL..44M \\''--atT12F ""64+=+=>r!   c                     |S Nr   )r   labelsrv   rn   s       r    transform_labelszRandomErasing.transform_labels)  s    r!   c                     |S rz   r   )r   bounding_boxesrv   rn   s       r    transform_bounding_boxesz&RandomErasing.transform_bounding_boxes,  s
     r!   c                     |S rz   r   )r   segmentation_masksrv   rn   s       r    transform_segmentation_masksz*RandomErasing.transform_segmentation_masks4  s
     "!r!   c                     |S rz   r   )r   input_shapes     r    compute_output_shapez"RandomErasing.compute_output_shape9  s    r!   c                     | j                   | j                  | j                  | j                  | j                  d}t
        |          }i ||S )N)r   r   r   r   r   )r   r   r   r   r   r   
get_config)r   configbase_configr   s      r    r   zRandomErasing.get_config<  sN    kkZZ//++II
 g(*(+(((r!   )rg   )g{Gz?gQ?N)r      NN)TN)NT)T)__name__
__module____qualname____doc___USE_BASE_FACTORr$   r   r   rE   r\   rd   rs   rx   r|   r   r   r   r   __classcell__)r   s   @r    r   r      sz    B N #6:""/b"HE
N, 	 <@"
	) 	)r!   r   N)keras.src.api_exportr   Qkeras.src.layers.preprocessing.image_preprocessing.base_image_preprocessing_layerr   keras.src.randomr   r   r   r!   r    <module>r      s7    - + *+|)/ |) ,|)r!   