U
    !?h5*                     @   s
  d dl Z d dlmZ d dlmZmZmZmZmZm	Z	 d dl
Zd dlZd dlmZmZmZmZmZmZ d dlmZ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! ddl"m#Z# ddl$m%Z% ddl&m'Z' e(d eedZ)G dd deZ*eee+e+e+edddZ,eeedddZ-eeedddZ.ee edddZ/eeeddd Z0ej1ej1d!d"d#Z2eee+e+e+e+f ed$d%d&Z3eed'd(d)Z4dd*d+d,Z5d3ee6eej1f e7e+e+e+ee' e7e7eee+e+e+e+f  e7ee ee ee6eej1f d0d1d2Z8dS )4    N)Enum)AnyListOptionalTupleUnioncast)BORDER_DEFAULTMORPH_ELLIPSE
MORPH_OPENGaussianBlurgetStructuringElementmorphologyEx)ImageImageOps)r   )estimate_alpha_cf)estimate_foreground_ml)stack_images)binary_erosion   )new_session)sessions_class)BaseSession   )r   r   c                   @   s   e Zd ZdZdZdZdS )
ReturnTyper   r      N)__name__
__module____qualname__BYTESPILLOWNDARRAY r"   r"   :/var/www/html/venv/lib/python3.8/site-packages/rembg/bg.pyr      s   r   )imgmaskforeground_thresholdbackground_thresholderode_structure_sizereturnc                 C   s   | j dks| j dkr| d} t| }t|}||k}||k }d}	|dkrbtj||ftjd}	t||	d}t||	dd	}tj|jtjd
d}
d|
|< d|
|< |d }|
d }t	||}t
||}t||}t|d ddtj}t|}|S )a  
    Perform alpha matting on an image using a given mask and threshold values.

    This function takes a PIL image `img` and a PIL image `mask` as input, along with
    the `foreground_threshold` and `background_threshold` values used to determine
    foreground and background pixels. The `erode_structure_size` parameter specifies
    the size of the erosion structure to be applied to the mask.

    The function returns a PIL image representing the cutout of the foreground object
    from the original image.
    RGBAZCMYKRGBNr   )dtype)	structurer   )r-   Zborder_value   )r,   Z
fill_value   g     o@)modeconvertnpasarrayZonesuint8r   fullshaper   r   r   Zclipastyper   	fromarray)r$   r%   r&   r'   r(   Z	img_arrayZ
mask_arrayZis_foregroundZis_backgroundr-   ZtrimapZimg_normalizedZtrimap_normalizedalpha
foregroundcutoutr"   r"   r#   alpha_matting_cutout%   s2    


 



r<   )r$   r%   r)   c                 C   s"   t d| jd}t | ||}|S )ac  
    Perform a simple cutout operation on an image using a mask.

    This function takes a PIL image `img` and a PIL image `mask` as input.
    It uses the mask to create a new image where the pixels from `img` are
    cut out based on the mask.

    The function returns a PIL image representing the cutout of the original
    image using the mask.
    r*   r   )r   newsizeZ	composite)r$   r%   emptyr;   r"   r"   r#   naive_cutoutZ   s    r@   c                 C   s   |  | | S )a  
    Apply the specified mask to the image as an alpha cutout.

    Args:
        img (PILImage): The image to be modified.
        mask (PILImage): The mask to be applied.

    Returns:
        PILImage: The modified image with the alpha cutout applied.
    )putalpha)r$   r%   r"   r"   r#   putalpha_cutoutj   s    
rB   )imgsr)   c                 C   s"   |  d}| D ]}t||}q|S )z
    Concatenate multiple images vertically.

    Args:
        imgs (List[PILImage]): The list of images to be concatenated.

    Returns:
        PILImage: The concatenated image.
    r   )popget_concat_v)rC   ZpivotZimr"   r"   r#   get_concat_v_multiy   s    

rF   )img1img2r)   c                 C   s<   t d| j| j|j f}|| d ||d| jf |S )z
    Concatenate two images vertically.

    Args:
        img1 (PILImage): The first image.
        img2 (PILImage): The second image to be concatenated below the first image.

    Returns:
        PILImage: The concatenated image.
    r*   )r   r   r   )r   r=   widthheightpaste)rG   rH   dstr"   r"   r#   rE      s    rE   )r%   r)   c                 C   s<   t | tt} t| dddtd} t| dk ddtj} | S )z
    Post Process the mask for a smooth boundary by applying Morphological Operations
    Research based on paper: https://www.sciencedirect.com/science/article/pii/S2352914821000757
    args:
        mask: Binary Numpy Mask
    )   rM   r   )ZsigmaXZsigmaYZ
borderType   r   r/   )	r   r   kernelr   r	   r2   wherer7   r4   r%   r"   r"   r#   post_process   s    rR   )r$   colorr)   c                 C   s6   |\}}}}t d| j||||f}|j| | d |S )a  
    Apply the specified background color to the image.

    Args:
        img (PILImage): The image to be modified.
        color (Tuple[int, int, int, int]): The RGBA color to be applied.

    Returns:
        PILImage: The modified image with the background color applied.
    r*   rQ   )r   r=   r>   rK   )r$   rS   rgbaZcolored_imager"   r"   r#   apply_background_color   s    rX   )r$   r)   c                 C   s   t tt| S )z
    Fix the orientation of the image based on its EXIF data.

    Args:
        img (PILImage): The image to be fixed.

    Returns:
        PILImage: The fixed image.
    )r   PILImager   Zexif_transpose)r$   r"   r"   r#   fix_image_orientation   s    
rZ   )r)   c                  C   s   t D ]} |   qdS )z/
    Download models for image processing.
    N)r   download_models)sessionr"   r"   r#   r[      s    r[   F   
   )dataalpha_matting"alpha_matting_foreground_threshold"alpha_matting_background_thresholdalpha_matting_erode_sizer\   	only_maskpost_process_maskbgcolorforce_return_bytesargskwargsr)   c
              	   O   s  t | ts|	r2tj}tttt	tt| }nRt | trNtj
}tt| }n6t | tjrrtj}ttt| }ntdt| |dd}t|}|dkrtd|
|}|j|f|
|}g }|D ]}|rttt|}|r|}nl|r>zt|||||}W n2 tk
r:   |r,t||}n
t||}Y nX n|rPt||}n
t||}|| q|}t|dkrt|}|dk	r|st||}tj
|kr|S tj|krt|S t	 }| |d |!d |" S )	a  
    Remove the background from an input image.

    This function takes in various parameters and returns a modified version of the input image with the background removed. The function can handle input data in the form of bytes, a PIL image, or a numpy array. The function first checks the type of the input data and converts it to a PIL image if necessary. It then fixes the orientation of the image and proceeds to perform background removal using the 'u2net' model. The result is a list of binary masks representing the foreground objects in the image. These masks are post-processed and combined to create a final cutout image. If a background color is provided, it is applied to the cutout image. The function returns the resulting cutout image in the format specified by the input 'return_type' parameter or as python bytes if force_return_bytes is true.

    Parameters:
        data (Union[bytes, PILImage, np.ndarray]): The input image data.
        alpha_matting (bool, optional): Flag indicating whether to use alpha matting. Defaults to False.
        alpha_matting_foreground_threshold (int, optional): Foreground threshold for alpha matting. Defaults to 240.
        alpha_matting_background_threshold (int, optional): Background threshold for alpha matting. Defaults to 10.
        alpha_matting_erode_size (int, optional): Erosion size for alpha matting. Defaults to 10.
        session (Optional[BaseSession], optional): A session object for the 'u2net' model. Defaults to None.
        only_mask (bool, optional): Flag indicating whether to return only the binary masks. Defaults to False.
        post_process_mask (bool, optional): Flag indicating whether to post-process the masks. Defaults to False.
        bgcolor (Optional[Tuple[int, int, int, int]], optional): Background color for the cutout image. Defaults to None.
        force_return_bytes (bool, optional): Flag indicating whether to return the cutout image as bytes. Defaults to False.
        *args (Optional[Any]): Additional positional arguments.
        **kwargs (Optional[Any]): Additional keyword arguments.

    Returns:
        Union[bytes, PILImage, np.ndarray]: The cutout image with the background removed.
    z^Input type {} is not supported. Try using force_return_bytes=True to force python bytes outputrA   FNu2netr   ZPNG)rj   )#
isinstancebytesr   r   r   rY   r   openioBytesIOr    r2   ndarrayr!   r8   
ValueErrorformattyperD   rZ   r   ZpredictrR   arrayr<   rB   r@   appendlenrF   rX   r3   saveseekread)r_   r`   ra   rb   rc   r\   rd   re   rf   rg   rh   ri   return_typer$   rA   ZmasksZcutoutsr%   r;   Zbior"   r"   r#   remove   sn    $




r{   )	Fr]   r^   r^   NFFNF)9rn   enumr   typingr   r   r   r   r   r   numpyr2   ZonnxruntimeZortZcv2r	   r
   r   r   r   r   ZPILr   r   Z	PIL.ImagerY   Z!pymatting.alpha.estimate_alpha_cfr   Z+pymatting.foreground.estimate_foreground_mlr   Zpymatting.util.utilr   Zscipy.ndimager   Zsession_factoryr   sessionsr   Zsessions.baser   Zset_default_logger_severityrO   r   intr<   r@   rB   rF   rE   rp   rR   rX   rZ   r[   rl   boolr{   r"   r"   r"   r#   <module>   sp     

5
         