o
    :ήc1                     @   sn   d 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d	Z		dddZdd ZdddZdS )a7  
Implementation of the masked normalized cross-correlation.

Based on the following publication:
D. Padfield. Masked object registration in the Fourier domain.
IEEE Transactions on Image Processing (2012)

and the author's original MATLAB implementation, available on this website:
http://www.dirkpadfield.com/
    )partialNnext_fast_len   )_supported_float_type333333?c              	   C   s   |du r| j |j krtd|t}| |f||ffD ]\}}|j |j kr)tdqt|| ||tt|jd|d}tj	t
|| kdd}tj|dd}	|	t| j  d }
t|j t| j  }|
 |d	  S )
aS  Masked image translation registration by masked normalized
    cross-correlation.

    Parameters
    ----------
    reference_image : ndarray
        Reference image.
    moving_image : ndarray
        Image to register. Must be same dimensionality as ``reference_image``,
        but not necessarily the same size.
    reference_mask : ndarray
        Boolean mask for ``reference_image``. The mask should evaluate
        to ``True`` (or 1) on valid pixels. ``reference_mask`` should
        have the same shape as ``reference_image``.
    moving_mask : ndarray or None, optional
        Boolean mask for ``moving_image``. The mask should evaluate to ``True``
        (or 1) on valid pixels. ``moving_mask`` should have the same shape
        as ``moving_image``. If ``None``, ``reference_mask`` will be used.
    overlap_ratio : float, optional
        Minimum allowed overlap ratio between images. The correlation for
        translations corresponding with an overlap ratio lower than this
        threshold will be ignored. A lower `overlap_ratio` leads to smaller
        maximum translation, while a higher `overlap_ratio` leads to greater
        robustness against spurious matches due to small overlap between
        masked images.

    Returns
    -------
    shifts : ndarray
        Shift vector (in pixels) required to register ``moving_image``
        with ``reference_image``. Axis ordering is consistent with
        numpy (e.g. Z, Y, X)

    References
    ----------
    .. [1] Dirk Padfield. Masked Object Registration in the Fourier Domain.
           IEEE Transactions on Image Processing, vol. 21(5),
           pp. 2706-2718 (2012). :DOI:`10.1109/TIP.2011.2181402`
    .. [2] D. Padfield. "Masked FFT registration". In Proc. Computer Vision and
           Pattern Recognition, pp. 2918-2925 (2010).
           :DOI:`10.1109/CVPR.2010.5540032`

    NzHInput images have different shapes, moving_mask must be explicitely set.z3Image sizes must match their respective mask sizes.full)axesmodeoverlap_ratio   )axisr   r   )shape
ValueErrorastypeboolcross_correlate_maskedtuplerangendimnpstacknonzeromaxmeanarray)reference_imagemoving_imagereference_maskmoving_maskr   immaskxcorrmaximacentershiftssize_mismatch r'   [/tmp/pip-target-vg8gfxp4/lib/python/skimage/registration/_masked_phase_cross_correlation.py_masked_phase_cross_correlation   s6   .


r)   r   c           '         sv  |dvrt d| dt| }t|}t|j|jg}	|	jdkr't d||	}tj|td}
||	}tj|td}t	|	j
}tt|j}|t| D ]}|j| |j| krft d| dqRt| j|D ]}|j| |j|  d	 |< qnttd
d D }tfdd|D }ttj||d}ttj||d  fdd}d|t|
< d|t|< t||d}t||d}||}||}||
|	}|||	}||| }t||dd< t|||dd< ||| }||| }||| }||| | 8 }|t|}||| }|t|| 8 }t|d|dd< |t|}||| } | t|| 8 } t| d| dd< t||  }!|| }|!| }!|| }|dkr|tt|j|d}"|"|!}!|"|}|"|}d| tjt|!|dd }#|!|#k}$tj|!|	d}%||$ |!|$  |%|$< tj|%dd	|%d |tj||dd }&d|%||&k < |%S )u  
    Masked normalized cross-correlation between arrays.

    Parameters
    ----------
    arr1 : ndarray
        First array.
    arr2 : ndarray
        Seconds array. The dimensions of `arr2` along axes that are not
        transformed should be equal to that of `arr1`.
    m1 : ndarray
        Mask of `arr1`. The mask should evaluate to `True`
        (or 1) on valid pixels. `m1` should have the same shape as `arr1`.
    m2 : ndarray
        Mask of `arr2`. The mask should evaluate to `True`
        (or 1) on valid pixels. `m2` should have the same shape as `arr2`.
    mode : {'full', 'same'}, optional
        'full':
            This returns the convolution at each point of overlap. At
            the end-points of the convolution, the signals do not overlap
            completely, and boundary effects may be seen.
        'same':
            The output is the same size as `arr1`, centered with respect
            to the `‘full’` output. Boundary effects are less prominent.
    axes : tuple of ints, optional
        Axes along which to compute the cross-correlation.
    overlap_ratio : float, optional
        Minimum allowed overlap ratio between images. The correlation for
        translations corresponding with an overlap ratio lower than this
        threshold will be ignored. A lower `overlap_ratio` leads to smaller
        maximum translation, while a higher `overlap_ratio` leads to greater
        robustness against spurious matches due to small overlap between
        masked images.

    Returns
    -------
    out : ndarray
        Masked normalized cross-correlation.

    Raises
    ------
    ValueError : if correlation `mode` is not valid, or array dimensions along
        non-transformation axes are not equal.

    References
    ----------
    .. [1] Dirk Padfield. Masked Object Registration in the Fourier Domain.
           IEEE Transactions on Image Processing, vol. 21(5),
           pp. 2706-2718 (2012). :DOI:`10.1109/TIP.2011.2181402`
    .. [2] D. Padfield. "Masked FFT registration". In Proc. Computer Vision and
           Pattern Recognition, pp. 2918-2925 (2010).
           :DOI:`10.1109/CVPR.2010.5540032`
    >   r   samezCorrelation mode 'z' is not valid.cz+complex-valued arr1, arr2 are not supported)dtypezVArray shapes along non-transformation axes should be equal, but dimensions along axis z	 are not.r   c                 S   s   g | ]	}t d t|qS )r   )sliceint).0szr'   r'   r(   
<listcomp>   s    z*cross_correlate_masked.<locals>.<listcomp>c                    s   g | ]}t  | qS r'   r   )r2   ax)final_shaper'   r(   r4      s    )sr	   c                    s
    | j S N)real)x)_ifftr'   r(   ifft   s   
z$cross_correlate_masked.<locals>.ifftg        )r	   Nr-   )newshaper	   g     @@T)r   keepdimsr,   )a_mina_maxout) r   r   asarrayr   r/   kindr   r   r   finfoepssetr   r   r   listr   r   	fftmodulefftnifftnlogical_not_fliproundfmaxsquaresqrt	_centeredr   abs
zeros_likeclip)'arr1arr2m1m2r
   r	   r   fixed_imager   float_dtype
fixed_maskr   rE   all_axesr   final_slice
fast_shapefftr<   rotated_moving_imagerotated_moving_mask	fixed_fftrotated_moving_fftfixed_mask_fftrotated_moving_mask_fftnumber_overlap_masked_pxmasked_correlated_fixed_fft$masked_correlated_rotated_moving_fft	numeratorfixed_squared_fftfixed_denomrotated_moving_squared_fftmoving_denomdenom
_centeringtolnonzero_indicesrA   number_px_thresholdr'   )r;   r6   r(   r   c   s   7






	



r   c                 C   sl   t |}t | j}tddg| j }|D ]}|| ||  d }|||  }t||||< q| t| S )zZ Return the center `newshape` portion of `arr`, leaving axes not
    in `axes` untouched. Nr   )r   rB   r   r   r0   r   r   )arrr=   r	   	currshapeslicesr5   startindendindr'   r'   r(   rQ     s   
rQ   c                 C   sX   |du rt dddg| j }nt dddg| j }|D ]
}t ddd||< q| t| S )z~ Reverse array over many axes. Generalization of arr[::-1] for many
    dimensions. If `axes` is `None`, flip along all axes. Nr,   )r0   r   r   )rs   r	   reverser   r'   r'   r(   rL   %  s   rL   )Nr   )r   r*   r   r8   )__doc__	functoolsr   numpyr   	scipy.fftr_   rH   r   _shared.utilsr   r)   r   rQ   rL   r'   r'   r'   r(   <module>   s    

O
 3