U
    hb                     @  s  d dl mZ d dlmZ d dlmZmZmZ d dlZd dl	Z
d dlmZmZ d dlmZmZmZmZmZmZmZmZmZmZ e
je
je
jdZejejejdZdd	d
ddddZdd	d
ddddZ dddddddZ!dd	d
ddddZ"eddddddZ#eddddddZ$dd	ddddZ%ddddd d!Z&ddd"dd#d$d%Z'ddddd&d'Z(edd(ddd)d*Zeddddd+d,Z)dd	ddd-d.Z*eddddd/d0Z+ddddd1d2Z,eddddd3d4Z-ddddd5d6Z.edd(ddd7d8Zdd	d	dd9d:d;Z/edd	d	dd9d<d=Z0edd	d	dd9d>d?Z1dd(d(dd9d@dAZ2dd	ddBdCdDZ3edddddEdFZ4edd	ddBdGdHZ5edd(ddBdIdJZddddddKdLdMZ6eddddddKdNdOZ7eddddddKdPdQZ8eddddddKdRdSZ9dd(d(ddTdUdVZ:edd(d(ddTdWdXZ;edd(d(ddTdYdZZ<edd(d(ddTd[d\Z=edd]dd^d_d`Z>edd]dd^dadbZ?edd]dd^dcddZ@dd]dd^dedfZAdddgddhdidjZBedddgddhdkdlZCedddgddhdmdnZDdddgddhdodpZEdddqdgddrdsdtZFedddqdgddrdudvZGdddqdgddrdwdxZHedddydzd{ZIedddyd|d}ZJdddyd~dZKedddyddZLedddyddZMdddyddZNdddddZOdddddZPdS )    )annotationswraps)AnyCallableLiteralN)
contiguouspreserve_channel_dim)
MAX_OPENCV_WORKING_CHANNELSMAX_VALUES_BY_DTYPEMONO_CHANNEL_DIMENSIONSNormalizationType	ValueTypeclipclippedconvert_valueget_max_valueget_num_channels)multiplyaddpowerztype[np.number]zfloat | np.ndarrayz%Literal[('add', 'multiply', 'power')]
np.ndarray)dtypevalue	operationreturnc                 C  sz   t |  }| tjkr$|dkr$t|}tj|tjddd}tjd|d tjd}|tkrht| ||S t	d| d S )Nr   r      r   zUnsupported operation: )
r   npuint8truncarrayfloat32reshapearangenp_operations
ValueError)r   r   r   	max_valuelut r*   6/tmp/pip-unpacked-wheel-rlprxnb3/albucore/functions.pycreate_lut_array   s    
r,   )imgr   r   r   c                   sh   j  t|ttfr2t ||}tt| S jd }t ||t	 fddt
|D S )Nr   c                   s4   g | ],}t d d d d |f t|  qS Ncv2LUTr   .0ir   r-   lutsr*   r+   
<listcomp>6   s     zapply_lut.<locals>.<listcomp>)r   
isinstanceintfloatr,   r0   r1   r   shapemergerange)r-   r   r   r)   num_channelsr*   r5   r+   	apply_lut-   s    
r?   znp.ndarray | floatzLiteral[('add', 'multiply')]c                 C  s  t |ttfr|dkr*| jtjkr*t|}t| }|tkr|dkrj|dk rPtjn| j}tj	| j
||d}n|dkrtj	| j
|tjd}nt |tjr|jtjkr|tj}|jdkr|ddd}t|| j
}|dkr| jtjkrt|dkrt|tjS t|tj}|S )Nr   r   r   r   r   r   )r8   r9   r:   r   r   r    r   r
   r#   fullr;   ndarrayfloat64astypendimr$   Zbroadcast_toallr   r!   )r-   r   r   r>   Z	cast_typer*   r*   r+   prepare_value_opencv9   s*    
rF   c                 C  s4   |dkr| j tjkrt|}t| | tj|S Nr   )r   r   r    int16r&   rC   r#   )r-   r   r   r*   r*   r+   apply_numpyV   s    
rI   )r-   r   r   c                 C  s   t | |dS Nr   r?   r-   r   r*   r*   r+   multiply_lut_   s    rM   c                 C  s8   t | |d}| jtjkr,t| tj|S t| |S rJ   )rF   r   r   r    r0   r   rC   r#   rL   r*   r*   r+   multiply_opencvd   s    rN   c                 C  s   t | |dS rJ   rI   rL   r*   r*   r+   multiply_numpyl   s    rP   r:   c                 C  s6   | j tjkrt| |S | j tjkr,t| |S t| |S r.   )r   r   r    rM   r#   rP   rN   rL   r*   r*   r+   multiply_by_constantp   s
    

rQ   r9   )r-   r   r>   r   c                 C  s2   | j tjkrt| |S |tkr(t| |S t| |S r.   )r   r   r    rM   r
   rP   rN   r-   r   r>   r*   r*   r+   multiply_by_vectorx   s
    

rS   c                 C  s
   t | |S r.   )rN   rL   r*   r*   r+   multiply_by_array   s    rT   r   c                 C  sV   t | }t||}t|ttfr*t| |S t|tjrL|jdkrLt	| ||S t
| |S Nr   )r   r   r8   r:   r9   rQ   r   rA   rD   rS   rT   rR   r*   r*   r+   r      s    

r   c                 C  s   t | |d}| jtjkrt|ttfrB|dk rBt| 	tj
|S t|tjrv|jtjkrvt| 	tj
|	tj
S t| |S t| |S )Nr   r   )rF   r   r   r    r8   r9   r:   r0   r   rC   r#   rA   rL   r*   r*   r+   
add_opencv   s    rV   c                 C  s   t | |dS rG   rO   rL   r*   r*   r+   	add_numpy   s    rW   c                 C  s   t | |dS rG   rK   rL   r*   r*   r+   add_lut   s    rX   c                 C  s
   t | |S r.   rV   rL   r*   r*   r+   add_constant   s    rZ   c                 C  s    | j tjkrt| |S t| |S r.   )r   r   r    rX   rV   rL   r*   r*   r+   
add_vector   s    
r[   c                 C  s
   t | |S r.   rY   rL   r*   r*   r+   	add_array   s    r\   c                 C  s   t | }t||}t|ttfrJ|dkr,| S | jtjkr@t|}t| |S | jtjkrb|	tj
}|jdkrvt| |S t| |S )Nr   r   )r   r   r8   r:   r9   r   r   r    rZ   rC   rH   rD   r[   r\   rR   r*   r*   r+   r      s    

r   )r-   meandenominatorr   c                 C  s   |  tj} | |8 } | | S r.   rC   r   r#   )r-   r]   r^   r*   r*   r+   normalize_numpy   s    r`   c                 C  s   |  tj} tj| tjd}tj| tjd}t|ttfrNtj| j|tjd}t|ttfrptj| j|tjd}||  tj}|| }t	
| |}t	j||t	jdS )Nr   )rC   r   r#   
zeros_liker8   r:   r9   r@   r;   r0   subtractr   CV_32F)r-   r]   r^   Zmean_imgZdenominator_imgresultr*   r*   r+   normalize_opencv   s    re   c                   s    j }t| }t }t|ttfr\t|ttfr\tjd|d tjd| | }t	
 |S t|tjr~|jdkr~|dd}t|tjr|dd}tjd|d tjd| | t	 fddt|D S )Nr   r   r   r*   r   c                   s.   g | ]&}t  d d d d |f | qS r.   r0   r1   r2   r-   r6   r*   r+   r7      s     z!normalize_lut.<locals>.<listcomp>)r   r   r   r8   r:   r9   r   r%   r#   r0   r1   rA   r;   r$   r<   r=   )r-   r]   r^   r   r(   r>   r)   r*   rg   r+   normalize_lut   s    rh   c                 C  s@   t | }t||}t||}| jtjkr4t| ||S t| ||S r.   )r   r   r   r   r    rh   re   )r-   r]   r^   r>   r*   r*   r+   	normalize   s    

ri   )r-   exponentr   c                 C  s   t | |dS Nr   rO   r-   rj   r*   r*   r+   power_numpy  s    rm   c                 C  s   | j tjkrt| |S | j tjkr<t||kr<t| |S | j tjkrjt|trj| 	tj}t||S t
d| j  d| dS )z(Handle the 'power' operation for OpenCV.zUnsupported image type z  for power operation with value N)r   r   r#   r0   powr    r9   r8   r:   rC   r'   )r-   r   	img_floatr*   r*   r+   power_opencv  s    rp   c                 C  s   t | |dS rk   rK   rl   r*   r*   r+   	power_lut  s    rq   c                 C  sJ   t | }t||}| jtjkr(t| |S t|ttfr@t	| |S t
| |S r.   )r   r   r   r   r    rq   r8   r:   r9   rp   rm   )r-   rj   r>   r*   r*   r+   r   "  s    


r   )img1weight1img2weight2r   c                 C  s    |  tj| | tj|  S r.   r_   rr   rs   rt   ru   r*   r*   r+   add_weighted_numpy/  s    rw   c                 C  s"   t | tj||tj|dS Nr   )r0   ZaddWeightedrC   r   r#   rv   r*   r*   r+   add_weighted_opencv3  s    ry   c           
      C  s   | j }t| }|dkr"|dkr"| S |dkr6|dkr6|S |dkrP|dkrPt| S |dkrj|dkrjt| |S tjd|d tjd| }t| |}tjd|d tjd| }t||}	t||	S )Nr   r   r   )	r   r   r   ra   r\   r%   r#   r0   r1   )
rr   rs   rt   ru   r   r(   Zlut1Zresult1Zlut2Zresult2r*   r*   r+   add_weighted_lut8  s    

rz   c                 C  s4   | j |j kr&td| j  d|j  dt| |||S )Nz/The input images must have the same shape. Got z and .)r;   r'   ry   rv   r*   r*   r+   add_weightedR  s    r|   )r-   factorr   r   c                 C  sr   t |ttfr<|dkr<t |ttfr<|dkr<tj| | jdS |dkrPt| |nt| }|dkrnt||S |S Nr   r   )r8   r9   r:   r   ra   r   r   r   r-   r}   r   rd   r*   r*   r+   multiply_add_numpyZ  s    ,r   c                 C  s   t |ttfr6|dkr6t |ttfr6|dkr6t| S | tj}|dkrftj|t	|| tj
dntj|| jd}|dkrtj|t	|| tj
d}|S r~   )r8   r9   r:   r   ra   rC   r#   r0   r   Z	ones_likeZCV_64Fr   r   r   r*   r*   r+   multiply_add_opencvf  s    ,
r   c                   s    j }t| }t }t|ttfrbt|ttfrbttjd|d tj	d| | |}t
 |S t|tjr|jdkr|dd}t|tjr|jdkr|dd}ttjd|d tj	d| | |t
 fddt|D S )Nr   r   r   r*   r   c                   s.   g | ]&}t  d d d d |f | qS r.   rf   r2   rg   r*   r+   r7     s     z$multiply_add_lut.<locals>.<listcomp>)r   r   r   r8   r:   r9   r   r   r%   r#   r0   r1   rA   r;   r$   r<   r=   )r-   r}   r   r   r(   r>   r)   r*   rg   r+   multiply_add_lutv  s    $$r   c                 C  s@   t | }t||}t||}| jtjkr4t| ||S t| ||S r.   )r   r   r   r   r    r   r   )r-   r}   r   r>   r*   r*   r+   multiply_add  s    

r   r   )r-   normalizationr   c                 C  s  |  tj} d}| jtkr(tj| dd} |dksF| jd dkr|dkr|   }| 	  | }| jd t
krt| |}t| |}tt| ||}|ddS |dkr.t| \}}|d d d	f }|d d d	f }| jd t
krt| |}t| |}tjt| ||tjd
}|ddS |dksR| jd dkr||dkr||  }|  }tj| d d	dtjtjdS |dkr| jdd}| jdd}| jd t
krt| |}t| |}tjt| ||| | tjd
ddS td| d S )N-C6?r   Zaxisimager   image_per_channel   r   r   min_maxmin_max_per_channel)alphabetaZ	norm_typer   r   r   Unknown normalization method: )rC   r   r#   rD   r   expand_dimsr;   r]   itemstdr
   	full_liker0   dividerb   r   Z
meanStdDevrc   minmaxri   ZNORM_MINMAXr'   )r-   r   epsr]   r   normalized_imgimg_minimg_maxr*   r*   r+   normalize_per_image_opencv  sB    

$
*r   c           
      C  s
  |  tj} d}| jtkr(tj| dd} |dkr\|  }|  | }| | | }|ddS |dkr| jdd}| jdd| }| | | }|ddS |d	kr| 	 }| 
 }	| | |	| |  S |d
kr| j	dd}| j
dd}	| | |	| |  S td| d S )Nr   r   r   r   r   r   r   r   r   r   r   )rC   r   r#   rD   r   r   r]   r   r   r   r   r'   )
r-   r   r   r]   r   r   
pixel_mean	pixel_stdr   r   r*   r*   r+   normalize_per_image_numpy  s.    
r   c                   s  j }t| d t}jtkr2tjdd|dksPjd dkr|dkr }	   }tj
dd tjd| | }t|d	d
S |dkrjddj	dd  fddt|D tfddt|D S |dksjd dkrX|dkrX  tj
dd tjd     }t|S |dkrjddjdd fddt|D tfddt|D S td| d S )Nr   r   r   r   r   r   r   r   r   r   r   c                   s2   g | ]*}t jd  d t jd|  |  qS r   r   r   r   r%   r#   r3   c)r(   r   r   r*   r+   r7     s    z+normalize_per_image_lut.<locals>.<listcomp>c                   s6   g | ].}t  d d d d |f | ddqS )Nr   r   r/   r2   rg   r*   r+   r7     s     r   r   c                   s>   g | ]6}t jd d t jd|  | |     qS r   r   r   )r   r   r   r(   r*   r+   r7     s   c                   s.   g | ]&}t  d d d d |f | qS r.   rf   r2   rg   r*   r+   r7     s     r   )r   r   r   rD   r   r   r   r;   r]   r   r%   r#   r0   r1   r   r=   r<   r   r   r'   )r-   r   r   r>   r]   r   r)   r*   )r   r-   r   r   r6   r(   r   r   r+   normalize_per_image_lut  s>    
$&
r   c                 C  s(   | j tjkr|dkrt| |S t| |S )NZper_image_per_channel)r   r   r    r   r   )r-   r   r*   r*   r+   normalize_per_image  s    
r   zfloat | None)r-   r(   r   c                 C  s"   |d krt | j}| | tjS r.   )r   r   rC   r   r#   r-   r(   r*   r*   r+   to_float_numpy  s    
r   c                 C  sR   |d krt | j}| tj}t| }|tkrFt||}t	||S t	||S r.   )
r   r   rC   r   r#   r   r
   r   r0   r   )r-   r(   ro   r>   max_value_arrayr*   r*   r+   to_float_opencv  s    
r   c                 C  sF   | j tjkrtd|d kr&t| j  }tjdtjd| }t| |S )Nz.LUT method is only applicable for uint8 images   r   )	r   r   r    r'   r   r%   r#   r0   r1   )r-   r(   r)   r*   r*   r+   to_float_lut1  s    
r   c                 C  sH   | j tjkr| tjS | j tjkr(| S | j tjkr>t| |S t| |S r.   )r   r   rB   rC   r#   r    r   r   r   r*   r*   r+   to_float<  s    
r   znp.dtype)r-   target_dtyper(   r   c                 C  s$   |d krt |}tt| | |S r.   )r   r   r   rintr-   r   r(   r*   r*   r+   from_float_numpyF  s    r   c                 C  sd   |d krt |}| tj}t| }|tkrPt||}ttt	
|||S tt| | |S r.   )r   rC   r   r#   r   r
   r   r   r   r0   r   )r-   r   r(   ro   r>   r   r*   r*   r+   from_float_opencvL  s    r   c                 C  sH   |t jkr| S |t jkr$| t jS | jt jkr<t| ||S t| ||S )a  Convert a floating-point image to the specified target data type.

    This function converts an input floating-point image to the specified target data type,
    scaling the values appropriately based on the max_value parameter or the maximum value
    of the target data type.

    Args:
        img (np.ndarray): Input floating-point image array.
        target_dtype (np.dtype): Target numpy data type for the output image.
        max_value (float | None, optional): Maximum value to use for scaling. If None,
            the maximum value of the target data type will be used. Defaults to None.

    Returns:
        np.ndarray: Image converted to the target data type.

    Notes:
        - If the input image is of type float32, the function uses OpenCV for faster processing.
        - For other input types, it falls back to a numpy-based implementation.
        - The function clips values to ensure they fit within the range of the target data type.
    )r   r#   rB   rC   r   r   r   r   r*   r*   r+   
from_float^  s    

r   )r-   r   c                 C  s   | d d d d ddf S Nr   .r*   r-   r*   r*   r+   hflip_numpy  s    r   c                 C  s   t | dS rU   r0   Zflipr   r*   r*   r+   	hflip_cv2  s    r   c                 C  s   t | S r.   )r   r   r*   r*   r+   hflip  s    r   c                 C  s   t | dS rx   r   r   r*   r*   r+   	vflip_cv2  s    r   c                 C  s   | d d ddf S r   r*   r   r*   r*   r+   vflip_numpy  s    r   c                 C  s   t | S r.   )r   r   r*   r*   r+   vflip  s    r   zCallable[..., np.ndarray])funcr   c                   s$   t  ddddd fdd}|S )ar  Decorator to ensure float32 input/output for image processing functions.

    This decorator converts the input image to float32 before passing it to the wrapped function,
    and then converts the result back to the original dtype if it wasn't float32.

    Args:
        func (Callable[..., np.ndarray]): The image processing function to be wrapped.

    Returns:
        Callable[..., np.ndarray]: A wrapped function that handles float32 conversion.

    Example:
        @float32_io
        def some_image_function(img: np.ndarray) -> np.ndarray:
            # Function implementation
            return processed_img
    r   r   r-   argskwargsr   c                   sB   | j }|tjkrt| }  | f||}|tjkr>t||dS |S N)r   )r   r   r#   r   r   r-   r   r   Zinput_dtyperd   r   r*   r+   float32_wrapper  s
    
z#float32_io.<locals>.float32_wrapperr   )r   r   r*   r   r+   
float32_io  s    r   c                   s$   t  ddddd fdd}|S )ah  Decorator to ensure uint8 input/output for image processing functions.

    This decorator converts the input image to uint8 before passing it to the wrapped function,
    and then converts the result back to the original dtype if it wasn't uint8.

    Args:
        func (Callable[..., np.ndarray]): The image processing function to be wrapped.

    Returns:
        Callable[..., np.ndarray]: A wrapped function that handles uint8 conversion.

    Example:
        @uint8_io
        def some_image_function(img: np.ndarray) -> np.ndarray:
            # Function implementation
            return processed_img
    r   r   r   c                   sD   | j }|tjkrt| tjd}  | f||}|tjkr@t|S |S r   )r   r   r    r   r   r   r   r*   r+   uint8_wrapper  s
    
zuint8_io.<locals>.uint8_wrapperr   )r   r   r*   r   r+   uint8_io  s    
r   )N)N)N)N)N)N)N)Q
__future__r   	functoolsr   typingr   r   r   r0   Znumpyr   Zalbucore.decoratorsr   r	   Zalbucore.utilsr
   r   r   r   r   r   r   r   r   r   r   r   r   r&   rn   Zcv2_operationsr,   r?   rF   rI   rM   rN   rP   rQ   rS   rT   rV   rW   rX   rZ   r[   r\   r`   re   rh   ri   rm   rp   rq   rw   ry   rz   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r*   r*   r*   r+   <module>   s   0	

. *

!