
    bi*                        d Z ddlmZ ddlZddlmZ ddlmZmZm	Z	 ddl
ZddlmZ ddlmc mc mZ ddlmZmZ ddlmZmZ dd	lmZmZ d
gZ G d d
e      Zy)zTransforms for text rendering and augmentation on images.

This module provides transforms for adding and manipulating text on images,
including text augmentation techniques like word insertion, deletion, and swapping.
    )annotationsN)Path)	AnnotatedAnyLiteral)AfterValidator)check_bboxesdenormalize_bboxes)check_range_boundsnondecreasing)BaseTransformInitSchemaImageOnlyTransform	TextImagec                       e Zd ZdZ G d de      Z	 	 	 	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d fdZedd       Z	 	 	 	 	 	 	 	 ddZ		 	 	 	 	 	 	 	 	 	 ddZ
ddZ	 	 	 	 	 	 	 	 dd	Zd fd
Z xZS )r   a  Apply text rendering transformations on images.

    This class supports rendering text directly onto images using a variety of configurations,
    such as custom fonts, font sizes, colors, and augmentation methods. The text can be placed
    inside specified bounding boxes.

    Args:
        font_path (str | Path): Path to the font file to use for rendering text.
        stopwords (list[str] | None): List of stopwords for text augmentation.
        augmentations (tuple[str | None, ...]): List of text augmentations to apply.
            None: text is printed as is
            "insertion": insert random stop words into the text.
            "swap": swap random words in the text.
            "deletion": delete random words from the text.
        fraction_range (tuple[float, float]): Range for selecting a fraction of bounding boxes to modify.
        font_size_fraction_range (tuple[float, float]): Range for selecting the font size as a fraction of
            bounding box height.
        font_color (tuple[float, ...]): Font color as RGB values (e.g., (0, 0, 0) for black).
        clear_bg (bool): Whether to clear the background before rendering text.
        metadata_key (str): Key to access metadata in the parameters.
        p (float): Probability of applying the transform.

    Targets:
        image, volume

    Image types:
        uint8, float32

    References:
        doc-augmentation: https://github.com/danaaubakirova/doc-augmentation

    Examples:
        >>> import albumentations as A
        >>> transform = A.Compose([
            A.TextImage(
                font_path=Path("/path/to/font.ttf"),
                stopwords=("the", "is", "in"),
                augmentations=("insertion", "deletion"),
                fraction_range=(0.5, 1.0),
                font_size_fraction_range=(0.5, 0.9),
                font_color=(255, 0, 0),  # red in RGB
                metadata_key="text_metadata",
                p=0.5
            )
        ])
        >>> transformed = transform(image=my_image, text_metadata=my_metadata)
        >>> image = transformed['image']
        # This will render text on `my_image` based on the metadata provided in `my_metadata`.

    c                  ^    e Zd ZU ded<   ded<   ded<   ded<   ded	<   d
ed<   ded<   ded<   y)TextImage.InitSchema
str | Path	font_pathtuple[str, ...]	stopwordsztuple[str | None, ...]augmentationszgAnnotated[tuple[float, float], AfterValidator(nondecreasing), AfterValidator(check_range_bounds(0, 1))]fraction_rangefont_size_fraction_rangetuple[float, ...]
font_colorboolclear_bgstrmetadata_keyN)__name__
__module____qualname____annotations__     g/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/albumentations/augmentations/text/transforms.py
InitSchemar   L   s;    ""--
 	

#
 	

 &%r%   r'   c
                    t         
|   |	       || _        || _        || _        || _        t        |      | _        || _        || _	        || _
        y )N)p)super__init__r   r   r   r   listr   r   r   r   )selfr   r   r   r   r   r   r   r   r)   	__class__s             r&   r+   zTextImage.__init__^   sV     	1(","!-0(@%$ r%   c                    | j                   gS )zGet list of targets that should be passed as parameters to transforms.

        Returns:
            list[str]: List containing the metadata key name

        )r   )r-   s    r&   targets_as_paramszTextImage.targets_as_paramst   s     !!""r%   c                    |j                         j                         D cg c]  }|s|	 }}t        |      }t        dt	        ||z              }|dk(  r-t        j                  ||| j                  | j                        }nY|dk(  r"t        j                  ||| j                        }n2|dk(  r"t        j                  ||| j                        }nt        d      t        j                  dd|      j                         }||k7  r|S dS c c}w )	a  Apply a random text augmentation to the input text.

        Args:
            text (str): Original text to augment
            fraction (float): Fraction of words to modify
            choice (Literal["insertion", "swap", "deletion"]): Type of augmentation to apply

        Returns:
            str: Augmented text or empty string if no change was made

        Raises:
            ValueError: If an invalid choice is provided

           	insertionswapdeletionz?Invalid choice. Choose from 'insertion', 'swap', or 'deletion'.z +  )stripsplitlenmaxintftextinsert_random_stopwordsr   	py_randomswap_random_wordsdelete_random_words
ValueErrorresub)	r-   textfractionchoicewordwords	num_wordsnum_words_to_modifyresult_sentences	            r&   
random_augzTextImage.random_aug~   s    ( #'**,"4"4"6?$$??J	!!SI)=%>?[ #;;ECVX\XfXfhlhvhvwOv#55e=PRVR`R`aOz!#77?RTXTbTbcO^__&&sO<BBD"1T"9ArA @s
   DDc                   	 ddl m} t        t	        j
                  |g             t        t	        j
                  |g      |j                  dd       d   }d |dd D        \  }}	}
}||	z
  } | j                  j                  | j                   }|j                  t        | j                        t        ||z              }| j                  r| j                  |}n=| j                  j!                  | j                        }||n| j#                  |d|	      }| j$                  }||	|
|f|||||d
S # t        $ r}t        d      |d}~ww xY w)a  Preprocess text metadata for a single bounding box.

        Args:
            image (np.ndarray): Input image
            bbox (tuple[float, float, float, float]): Normalized bounding box coordinates
            text (str): Text to render in the bounding box
            bbox_index (int): Index of the bounding box in the original metadata

        Returns:
            dict[str, Any]: Processed metadata including font, position, and text information

        Raises:
            ImportError: If PIL.ImageFont is not installed

        r   )	ImageFontz`ImageFont from PIL is required to use TextImage transform. Install it with `pip install Pillow`.N   c              3  2   K   | ]  }t        |        y wN)r<   ).0xs     r&   	<genexpr>z0TextImage.preprocess_metadata.<locals>.<genexpr>   s     %Lc!f%Ls            ?)rG   )bbox_coords
bbox_indexoriginal_textrE   fontr   )PILrO   ImportErrorr	   nparrayr
   shaper?   uniformr   truetyper   r   r<   r   rG   rM   r   )r-   imagebboxrE   rY   rO   errdenormalized_bboxx_miny_minx_maxy_maxbbox_heightfont_size_fractionr[   augmented_textaugmentationr   s                     r&   preprocess_metadatazTextImage.preprocess_metadata   sT   ,	%
 	RXXtf%&.rxx/?RaQRST%L6G6K%L"ueUem3T^^33T5R5RS!!#dnn"5s;MP[;[7\]!!T%7%7%?!N>>001C1CDL%1%9TttUXam?nN__
 "5%7$!"$
 	
/  	r	s   D2 2	E;EEc           	        d|v r|d   n|d   d   }|| j                      }|g k(  rdg iS t        |t              r|g} | j                  j                  | j
                   }t        t        |      |z        }| j                  j                  t        t        |            |      }|D cg c]"  }| j                  |||   d   ||   d   |      $ }	}d|	iS c c}w )aL  Generate parameters based on input data.

        Args:
            params (dict[str, Any]): Dictionary of existing parameters
            data (dict[str, Any]): Dictionary containing input data with image and metadata

        Returns:
            dict[str, Any]: Dictionary containing the overlay data for text rendering

        rc   imagesr   overlay_datard   rE   )r   
isinstancedictr?   ra   r   r<   r:   samplerangero   )
r-   paramsdatarc   metadatarF   num_bboxes_to_modifybbox_indices_to_updaterY   rr   s
             r&   get_params_dependent_on_dataz&TextImage.get_params_dependent_on_data   s    ")DWd8nQ6G))*r>  h% zH)4>>))4+>+>?"3x=8#;<!%!6!6uS]7KMa!b 5
 $$UHZ,@,H(S]J^_eJfhrs
 
 L
 	

s   )'Cc                F    t        j                  ||| j                        S )aL  Apply text rendering to the input image.

        Args:
            img (np.ndarray): Input image
            overlay_data (list[dict[str, Any]]): List of dictionaries containing text rendering information
            **params (Any): Additional parameters

        Returns:
            np.ndarray: Image with rendered text

        )r   )r=   render_textr   )r-   imgrr   rw   s       r&   applyzTextImage.apply   s    "   lT]]KKr%   c           	         t        |   |g|i |}|d   D cg c]  }|d   |d   |d   |d   |d   d c}|d<   |S c c}w )a  Apply the transform and include overlay data in the result.

        Args:
            params (dict[str, Any]): Parameters for the transform
            *args (Any): Additional positional arguments
            **kwargs (Any): Additional keyword arguments

        Returns:
            dict[str, Any]: Dictionary containing the transformed data and simplified overlay information

        rr   rX   rE   rZ   rY   r   )rX   rE   rZ   rY   r   )r*   apply_with_params)r-   rw   argskwargsresoverlayr.   s         r&   r   zTextImage.apply_with_params  sy     g'@@@ ".1	
   '}5!(!9%l3%l3	
N 
	
s   A))theisinatofrR   )      ?r   )g?g?)r   r   r   Ftextimage_metadatarW   )r   r   r   r   r   z;tuple[Literal['insertion', 'swap', 'deletion'] | None, ...]r   tuple[float, float]r   r   r   r   r   r   r   r   r)   floatreturnNone)r   z	list[str])rE   r   rF   r   rG   z(Literal['insertion', 'swap', 'deletion']r   r   )
rc   
np.ndarrayrd   z!tuple[float, float, float, float]rE   r   rY   r<   r   dict[str, Any])rw   r   rx   r   r   r   )r   r   rr   zlist[dict[str, Any]]rw   r   r   r   )rw   r   r   r   r   r   r   r   )r    r!   r"   __doc__r   r'   r+   propertyr0   rM   ro   r|   r   r   __classcell__)r.   s   @r&   r   r      sT   1f, * &EU\.88B(10!! #! S	!
 ,! #6! &! ! ! ! 
!, # #"B"B "B 9	"B
 
"BH6
6
 06
 	6

 6
 
6
p$
LLL +L 	L
 
L& r%   )r   
__future__r   rC   pathlibr   typingr   r   r   numpyr^   pydanticr   ,albumentations.augmentations.text.functionalr   rE   
functionalr=   albumentations.core.bbox_utilsr	   r
   albumentations.core.pydanticr   r   (albumentations.core.transforms_interfacer   r   __all__r   r$   r%   r&   <module>r      sF    # 	  * *  # < < K J `-S" Sr%   