a
    d                     @   s`   d dl Z d dlZd dlZdddZdddZdd	d
ZdddZejfddZ	ej
fddZdS )    NFc              	   O   sT  |r|dv sJ t | t j}|jdkr>t|  d|j d|j| d dksTJ tj|d|d\}}t||g|R i |}nt	| d}	z|	
dd	}
W n  ty   td
|  Y n0 |
dkrtd
|  dt|	tjd }t|	tjd }t|	tj|| d ||df}W d   n1 s>0    Y  |tjS )a  Read an optical flow map.

    Args:
        flow_path (ndarray or str): Flow path.
        quantize (bool): whether to read quantized pair, if set to True,
            remaining args will be passed to :func:`dequantize_flow`.
        concat_axis (int): The axis that dx and dy are concatenated,
            can be either 0 or 1. Ignored if quantize is False.

    Returns:
        ndarray: Optical flow represented as a (h, w, 2) numpy array
    r         z6 is not a valid quantized flow file, its dimension is .r   Zaxisrb   utf-8zInvalid flow file: PIEHz, header does not contain PIEHr   N)cv2ZimreadZIMREAD_UNCHANGEDndimIOErrorshapenpsplitdequantize_flowopenreaddecode	Exceptionfromfileint32Zsqueezefloat32Zreshapeastype)Z	flow_pathquantizeconcat_axisargskwargsZcat_flowdxdyflowfheaderwh r%   `/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/basicsr/utils/flow_util.pyflowread   s&    
Dr'   c           
      O   s   |st |dd}|dd tj| jd | jd gtjd| | tj	} | | |
  W d   q1 sx0    Y  nZ|dv sJ t| g|R i |\}}tj||f|d	}	tjtj|d
d t||	 dS )a  Write optical flow to file.

    If the flow is not quantized, it will be saved as a .flo file losslessly,
    otherwise a jpeg image which is lossy but of much smaller size. (dx and dy
    will be concatenated horizontally into a single image if quantize is True.)

    Args:
        flow (ndarray): (h, w, 2) array of optical flow.
        filename (str): Output filepath.
        quantize (bool): Whether to quantize the flow and save it to 2 jpeg
            images. If set to True, remaining args will be passed to
            :func:`quantize_flow`.
        concat_axis (int): The axis that dx and dy are concatenated,
            can be either 0 or 1. Ignored if quantize is False.
    wbr
   r	   r   r   )dtypeNr   r   T)exist_ok)r   writeencoder   arrayr   r   tofiler   r   flushquantize_flowZconcatenateosmakedirspathdirnamer   Zimwrite)
r    filenamer   r   r   r   r!   r   r   Zdxdyr%   r%   r&   	flowwrite-   s    &
(r6   {Gz?Tc           	         sN   | j \}}}| d }| d }|r0|| }|| } fdd||fD }t|S )a  Quantize flow to [0, 255].

    After this step, the size of flow will be much smaller, and can be
    dumped as jpeg images.

    Args:
        flow (ndarray): (h, w, 2) array of optical flow.
        max_val (float): Maximum value of flow, values beyond
                        [-max_val, max_val] will be truncated.
        norm (bool): Whether to divide flow values by image width/height.

    Returns:
        tuple[ndarray]: Quantized dx and dy.
    ).r   ).r   c                    s    g | ]}t |   d tjqS    )r   r   Zuint8.0dmax_valr%   r&   
<listcomp>b       z!quantize_flow.<locals>.<listcomp>)r   tuple)	r    r>   Znormr$   r#   _r   r   Z
flow_compsr%   r=   r&   r0   L   s    r0   c                    s   | j |j ksJ | jdks6| jdkr2| j d dks6J  fdd| |fD \} }|rp| | j d 9 } || j d 9 }t| |f}|S )a,  Recover from quantized flow.

    Args:
        dx (ndarray): Quantized dx.
        dy (ndarray): Quantized dy.
        max_val (float): Maximum value used when quantizing.
        denorm (bool): Whether to multiply flow values with width/height.

    Returns:
        ndarray: Dequantized flow.
    r      r   c                    s   g | ]}t |   d qS r8   )
dequantizer:   r=   r%   r&   r?   u   r@   z#dequantize_flow.<locals>.<listcomp>r   )r   r   r   Zdstack)r   r   r>   Zdenormr    r%   r=   r&   r   f   s    &r   c                 C   s|   t |tr|dks td| ||kr>td| d| dt| ||| } tt||  ||  ||d }|S )ag  Quantize an array of (-inf, inf) to [0, levels-1].

    Args:
        arr (ndarray): Input array.
        min_val (scalar): Minimum value to be clipped.
        max_val (scalar): Maximum value to be clipped.
        levels (int): Quantization levels.
        dtype (np.type): The type of the quantized array.

    Returns:
        tuple: Quantized array.
    r   +levels must be a positive integer, but got 	min_val ( ) must be smaller than max_val ())
isinstanceint
ValueErrorr   ZclipZminimumfloorr   )arrmin_valr>   levelsr)   Zquantized_arrr%   r%   r&   r   ~   s    (r   c                 C   s`   t |tr|dks td| ||kr>td| d| d| d |||  | | }|S )aM  Dequantize an array.

    Args:
        arr (ndarray): Input array.
        min_val (scalar): Minimum value to be clipped.
        max_val (scalar): Maximum value to be clipped.
        levels (int): Quantization levels.
        dtype (np.type): The type of the dequantized array.

    Returns:
        tuple: Dequantized array.
    r   rF   rG   rH   rI   g      ?)rJ   rK   rL   r   )rN   rO   r>   rP   r)   Zdequantized_arrr%   r%   r&   rE      s    rE   )Fr   )Fr   )r7   T)r7   T)r   numpyr   r1   r'   r6   r0   r   int64r   float64rE   r%   r%   r%   r&   <module>   s   
&


