U
    ?h8                     @   s   d Z ddlmZ ddlmZ ddl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mZ dd ZddddddejdddZdd ZddddejdddZdS )z.TV-L1 optical flow algorithm implementation.

    )partial)combinations_with_replacementN)ndimage   )gaussian)_supported_float_type)warp   )coarse_to_fineget_warp_pointsc	           !         s  | j  tj fdd| jD ddd}	d| j }
d}|| }|
| }|| j9 }| }}tj| jf| j  d}tj| j| jf| j  d}td	g|j }td	g|j }td	g|jd  }t|D ]}|rt	
|d
g| jdg  }t|t|	|dd}tt|}|| d}d
||dk< ||  || d }t|D ]}||| d }t||| k}|}|d	d	|f  || |d	d	|f  ||  8  < | }|t||  }|d	d	|f  ||d	d	|f  8  < | }t| jD ]Z}||d< t|D ]@}t| jD ]J}||d< tdd||d
 < tj|| |d|t|< td	||d
 < q t|d dtjdf }||9 }|d7 }||  |
| 8  < ||  |  < || d } t| jD ]f}||d
< tdd||d < td
d	||< | t|  |t| 7  < td	||d < td	||< q|| |  ||< qqqH||8 }||  |k r| q|}q|S )u  TV-L1 solver for optical flow estimation.

    Parameters
    ----------
    reference_image : ndarray, shape (M, N[, P[, ...]])
        The first gray scale image of the sequence.
    moving_image : ndarray, shape (M, N[, P[, ...]])
        The second gray scale image of the sequence.
    flow0 : ndarray, shape (image0.ndim, M, N[, P[, ...]])
        Initialization for the vector field.
    attachment : float
        Attachment parameter. The smaller this parameter is,
        the smoother is the solutions.
    tightness : float
        Tightness parameter. It should have a small value in order to
        maintain attachment and regularization parts in
        correspondence.
    num_warp : int
        Number of times moving_image is warped.
    num_iter : int
        Number of fixed point iteration.
    tol : float
        Tolerance used as stopping criterion based on the L² distance
        between two consecutive values of (u, v).
    prefilter : bool
        Whether to prefilter the estimated optical flow before each
        image warp.

    Returns
    -------
    flow : ndarray, shape ((image0.ndim, M, N[, P[, ...]])
        The estimated optical flow components for each axis.

    c                    s   g | ]}t j| d qS dtypenpZarange.0nr    T/var/www/html/venv/lib/python3.8/site-packages/skimage/registration/_optical_flow.py
<listcomp>7   s   z_tvl1.<locals>.<listcomp>ijTZindexingsparseg      ?r   r   Nr	      edgemoder   Zaxis.g      ?)r   r   meshgridshapendimsizezerosslicerangendimedian_filterr   r   arraygradientsumabssigncopydifftuplesqrtZnewaxis)!reference_imagemoving_imageflow0
attachment	tightnessnum_warpnum_itertol	prefiltergriddtZreg_num_iterZf0f1Zflow_currentZflow_previousgZprojZs_gZs_pZs_d_Zimage1_warpgradZNIZrho_0rhoidxZflow_auxiliaryZsrhoZaxZnormdr   r   r   _tvl1   s    % 

4(rD      g333333?   
   g-C6?F)r5   r6   r7   r8   r9   r:   r   c             	   C   sL   t t||||||d}	t|t|kr<d| d}
t|
t| ||	|dS )u  Coarse to fine optical flow estimator.

    The TV-L1 solver is applied at each level of the image
    pyramid. TV-L1 is a popular algorithm for optical flow estimation
    introduced by Zack et al. [1]_, improved in [2]_ and detailed in [3]_.

    Parameters
    ----------
    reference_image : ndarray, shape (M, N[, P[, ...]])
        The first gray scale image of the sequence.
    moving_image : ndarray, shape (M, N[, P[, ...]])
        The second gray scale image of the sequence.
    attachment : float, optional
        Attachment parameter (:math:`\lambda` in [1]_). The smaller
        this parameter is, the smoother the returned result will be.
    tightness : float, optional
        Tightness parameter (:math:`\tau` in [1]_). It should have
        a small value in order to maintain attachment and
        regularization parts in correspondence.
    num_warp : int, optional
        Number of times moving_image is warped.
    num_iter : int, optional
        Number of fixed point iteration.
    tol : float, optional
        Tolerance used as stopping criterion based on the L² distance
        between two consecutive values of (u, v).
    prefilter : bool, optional
        Whether to prefilter the estimated optical flow before each
        image warp. When True, a median filter with window size 3
        along each axis is applied. This helps to remove potential
        outliers.
    dtype : dtype, optional
        Output data type: must be floating point. Single precision
        provides good results and saves memory usage and computation
        time compared to double precision.

    Returns
    -------
    flow : ndarray, shape ((image0.ndim, M, N[, P[, ...]])
        The estimated optical flow components for each axis.

    Notes
    -----
    Color images are not supported.

    References
    ----------
    .. [1] Zach, C., Pock, T., & Bischof, H. (2007, September). A
       duality based approach for realtime TV-L 1 optical flow. In Joint
       pattern recognition symposium (pp. 214-223). Springer, Berlin,
       Heidelberg. :DOI:`10.1007/978-3-540-74936-3_22`
    .. [2] Wedel, A., Pock, T., Zach, C., Bischof, H., & Cremers,
       D. (2009). An improved algorithm for TV-L 1 optical flow. In
       Statistical and geometrical approaches to visual motion analysis
       (pp. 23-45). Springer, Berlin, Heidelberg.
       :DOI:`10.1007/978-3-642-03061-1_2`
    .. [3] Pérez, J. S., Meinhardt-Llopis, E., & Facciolo,
       G. (2013). TV-L1 optical flow estimation. Image Processing On
       Line, 2013, 137-150. :DOI:`10.5201/ipol.2013.26`

    Examples
    --------
    >>> from skimage.color import rgb2gray
    >>> from skimage.data import stereo_motorcycle
    >>> from skimage.registration import optical_flow_tvl1
    >>> image0, image1, disp = stereo_motorcycle()
    >>> # --- Convert the images to gray level: color is not supported.
    >>> image0 = rgb2gray(image0)
    >>> image1 = rgb2gray(image1)
    >>> flow = optical_flow_tvl1(image1, image0)

    )r5   r6   r7   r8   r9   r:   dtype=. is not supported. Try 'float32' or 'float64.'r   )r   rD   r   r   r   
ValueErrorr
   )r2   r3   r5   r6   r7   r8   r9   r:   r   solvermsgr   r   r   optical_flow_tvl1   s    M   rM   c                    s  | j  | j}d| d }|r:||d f }	tt|	dd}
nttj||f dd}
|}tj| j||f  d}tj| j|f  d}tj	 fdd	| jD d
dd}t
|D ]}|rt|d|d  }t|t||dd}tjt|dd}|| jdd|  | }tt
|dD ]6\}}|
|| ||   |d||f< |d||f< qt
|D ]}|
|| | |d|f< qXttj|dk }tj| d||< d||< ttj|||d}q|S )a  Iterative Lucas-Kanade (iLK) solver for optical flow estimation.

    Parameters
    ----------
    reference_image : ndarray, shape (M, N[, P[, ...]])
        The first gray scale image of the sequence.
    moving_image : ndarray, shape (M, N[, P[, ...]])
        The second gray scale image of the sequence.
    flow0 : ndarray, shape (reference_image.ndim, M, N[, P[, ...]])
        Initialization for the vector field.
    radius : int
        Radius of the window considered around each pixel.
    num_warp : int
        Number of times moving_image is warped.
    gaussian : bool
        if True, a gaussian kernel is used for the local
        integration. Otherwise, a uniform kernel is used.
    prefilter : bool
        Whether to prefilter the estimated optical flow before each
        image warp. This helps to remove potential outliers.

    Returns
    -------
    flow : ndarray, shape ((reference_image.ndim, M, N[, P[, ...]])
        The estimated optical flow components for each axis.

    r   r	      Zmirror)sigmar   )r#   r   r   c                    s   g | ]}t j| d qS r   r   r   r   r   r   r     s   z_ilk.<locals>.<listcomp>r   Tr   )r	   )r   r   r   r   r   .g+=)r   r"   r   gaussian_filterr'   Zuniform_filterr   r$   r!   r    r&   r(   r   r   stackr*   r+   r   r,   ZlinalgZdeteyeZmoveaxisZsolve)r2   r3   r4   radiusr7   r   r:   r"   r#   rO   Zfilter_funcZflowAbr;   r?   Zmoving_image_warpr@   Zerror_imageijrB   r   r   r   _ilk   sN     0rX      )rS   r7   r   r:   r   c          	      C   sH   t t||||d}t|t|kr8d| d}t|t| |||dS )a<
  Coarse to fine optical flow estimator.

    The iterative Lucas-Kanade (iLK) solver is applied at each level
    of the image pyramid. iLK [1]_ is a fast and robust alternative to
    TVL1 algorithm although less accurate for rendering flat surfaces
    and object boundaries (see [2]_).

    Parameters
    ----------
    reference_image : ndarray, shape (M, N[, P[, ...]])
        The first gray scale image of the sequence.
    moving_image : ndarray, shape (M, N[, P[, ...]])
        The second gray scale image of the sequence.
    radius : int, optional
        Radius of the window considered around each pixel.
    num_warp : int, optional
        Number of times moving_image is warped.
    gaussian : bool, optional
        If True, a Gaussian kernel is used for the local
        integration. Otherwise, a uniform kernel is used.
    prefilter : bool, optional
        Whether to prefilter the estimated optical flow before each
        image warp. When True, a median filter with window size 3
        along each axis is applied. This helps to remove potential
        outliers.
    dtype : dtype, optional
        Output data type: must be floating point. Single precision
        provides good results and saves memory usage and computation
        time compared to double precision.

    Returns
    -------
    flow : ndarray, shape ((reference_image.ndim, M, N[, P[, ...]])
        The estimated optical flow components for each axis.

    Notes
    -----
    - The implemented algorithm is described in **Table2** of [1]_.
    - Color images are not supported.

    References
    ----------
    .. [1] Le Besnerais, G., & Champagnat, F. (2005, September). Dense
       optical flow by iterative local window registration. In IEEE
       International Conference on Image Processing 2005 (Vol. 1,
       pp. I-137). IEEE. :DOI:`10.1109/ICIP.2005.1529706`
    .. [2] Plyer, A., Le Besnerais, G., & Champagnat,
       F. (2016). Massively parallel Lucas Kanade optical flow for
       real-time video processing applications. Journal of Real-Time
       Image Processing, 11(4), 713-730. :DOI:`10.1007/s11554-014-0423-0`

    Examples
    --------
    >>> from skimage.color import rgb2gray
    >>> from skimage.data import stereo_motorcycle
    >>> from skimage.registration import optical_flow_ilk
    >>> reference_image, moving_image, disp = stereo_motorcycle()
    >>> # --- Convert the images to gray level: color is not supported.
    >>> reference_image = rgb2gray(reference_image)
    >>> moving_image = rgb2gray(moving_image)
    >>> flow = optical_flow_ilk(moving_image, reference_image)

    )rS   r7   r   r:   rH   rI   r   )r   rX   r   r   r   rJ   r
   )	r2   r3   rS   r7   r   r:   r   rK   rL   r   r   r   optical_flow_ilk6  s    C
rZ   )__doc__	functoolsr   	itertoolsr   numpyr   Zscipyr   r'   Z_shared.filtersr   rP   Z_shared.utilsr   Z	transformr   Z_optical_flow_utilsr
   r   rD   Zfloat32rM   rX   rZ   r   r   r   r   <module>   s2         XP   