
    9i                        S SK r S SKrS SKJr  S SKrS SKJr  S SKJ	r	J
r
  SSKJr  SSKJrJrJr  SSKJr  SS	KJr  S
SKJr  S
SKJrJrJr  S
SKJr  S
SKJrJr  S$S jrS%S jr S&S jr! S'S jr"S(S jr#S r$S r%S r&S r'S)S jr(S$S jr)S*S jr*S+S jr+S+S jr,S,S jr-S-S jr.S
SSSS\R^                  SS4\R^                  \R^                  S .S! jjr0S+S" jr1S# r2g).    N)combinations_with_replacement)ndimage)spatialstats   )gaussian)_supported_float_typesafe_as_intwarn)integral_image)img_as_float   )_hessian_matrix_det)_corner_fast_corner_moravec_corner_orientations)peak_local_max)_prepare_grayscale_input_2D_prepare_grayscale_input_nDc           
          [        U R                  5       Vs/ s H  n[        R                  " XXS9PM     nnU$ s  snf )a  Compute derivatives in axis directions using the Sobel operator.

Parameters
----------
image : ndarray
    Input image.
mode : {'constant', 'reflect', 'wrap', 'nearest', 'mirror'}, optional
    How to handle values outside the image borders.
cval : float, optional
    Used in conjunction with mode 'constant', the value outside
    the image boundaries.

Returns
-------
derivatives : list of ndarray
    Derivatives in each axis direction.

)axismodecval)rangendimndisobel)imager   r   iderivativess        V/var/www/html/land-doc-ocr/venv/lib/python3.13/site-packages/skimage/feature/corner.py_compute_derivativesr"      sD    * AFejj@Q@Q1		%d6@Q   	s   ;c                    US:X  a  U R                   S:  a  [        S5      eUS;  a  [        SU S35      e[        R                  " U5      (       d/  [	        U5      n[        U5      U R                   :w  a  [        S5      e[        U 5      n [        XUS9nUS:X  a  [        U5      n[        US5       VVs/ s H  u  pg[        Xg-  XUS	9PM     nnnU$ s  snnf )
a  Compute structure tensor using sum of squared differences.

The (2-dimensional) structure tensor A is defined as::

    A = [Arr Arc]
        [Arc Acc]

which is approximated by the weighted sum of squared differences in a local
window around each pixel in the image. This formula can be extended to a
larger number of dimensions (see [1]_).

Parameters
----------
image : ndarray
    Input image.
sigma : float or array-like of float, optional
    Standard deviation used for the Gaussian kernel, which is used as a
    weighting function for the local summation of squared differences.
    If sigma is an iterable, its length must be equal to `image.ndim` and
    each element is used for the Gaussian kernel applied along its
    respective axis.
mode : {'constant', 'reflect', 'wrap', 'nearest', 'mirror'}, optional
    How to handle values outside the image borders.
cval : float, optional
    Used in conjunction with mode 'constant', the value outside
    the image boundaries.
order : {'rc', 'xy'}, optional
    NOTE: 'xy' is only an option for 2D images, higher dimensions must
    always use 'rc' order. This parameter allows for the use of reverse or
    forward order of the image axes in gradient computation. 'rc' indicates
    the use of the first axis initially (Arr, Arc, Acc), whilst 'xy'
    indicates the usage of the last axis initially (Axx, Axy, Ayy).

Returns
-------
A_elems : list of ndarray
    Upper-diagonal elements of the structure tensor for each pixel in the
    input image.

Examples
--------
>>> from skimage.feature import structure_tensor
>>> square = np.zeros((5, 5))
>>> square[2, 2] = 1
>>> Arr, Arc, Acc = structure_tensor(square, sigma=0.1, order='rc')
>>> Acc
array([[0., 0., 0., 0., 0.],
       [0., 1., 0., 1., 0.],
       [0., 4., 0., 4., 0.],
       [0., 1., 0., 1., 0.],
       [0., 0., 0., 0., 0.]])

See also
--------
structure_tensor_eigenvalues

References
----------
.. [1] https://en.wikipedia.org/wiki/Structure_tensor
xyr   z)Only "rc" order is supported for dim > 2.rcr$   zorder z( is invalid. Must be either "rc" or "xy"z2sigma must have as many elements as image has axesr   r   sigmar   r   )r   
ValueErrornpisscalartuplelenr   r"   reversedr   r   )	r   r)   r   r   orderr    der0der1A_elemss	            r!   structure_tensorr4   .   s    z }aDEEL 6%(PQRR;;ueu:#TUU'.E&udCK}{+
 8QGGJD 	E4@G  
 Ns   6Cc           	      P  ^^ [        U 5      n [        U R                  5      nU R                  USS9n U R                  S:  a  US:X  a  [        S5      eUS;  a  [        SU 35      e[        R                  " U5      (       a  U4U R                  -  n[        S U 5       5      (       a  S	OS
nS[        R                  " S5      -  m[        U4S jU 5       5      n[        XrX6S9n[        R                  " [        R                   40 UD6n	U R                  m[        U4S j[#        T5       5       5      n
[#        T5       Vs/ s H  o" X
U   S9PM     nn[#        T5      nUS:X  a  [%        U5      n['        US5       VVs/ s H  u  pU	" X   X   S9PM     nnnU$ s  snf s  snnf )a  Compute the Hessian via convolutions with Gaussian derivatives.

In 2D, the Hessian matrix is defined as:
    H = [Hrr Hrc]
        [Hrc Hcc]

which is computed by convolving the image with the second derivatives
of the Gaussian kernel in the respective r- and c-directions.

The implementation here also supports n-dimensional data.

Parameters
----------
image : ndarray
    Input image.
sigma : float or sequence of float, optional
    Standard deviation used for the Gaussian kernel, which sets the
    amount of smoothing in terms of pixel-distances. It is
    advised to not choose a sigma much less than 1.0, otherwise
    aliasing artifacts may occur.
mode : {'constant', 'reflect', 'wrap', 'nearest', 'mirror'}, optional
    How to handle values outside the image borders.
cval : float, optional
    Used in conjunction with mode 'constant', the value outside
    the image boundaries.
order : {'rc', 'xy'}, optional
    This parameter allows for the use of reverse or forward order of
    the image axes in gradient computation. 'rc' indicates the use of
    the first axis initially (Hrr, Hrc, Hcc), whilst 'xy' indicates the
    usage of the last axis initially (Hxx, Hxy, Hyy)

Returns
-------
H_elems : list of ndarray
    Upper-diagonal elements of the hessian matrix for each pixel in the
    input image. In 2D, this will be a three element list containing [Hrr,
    Hrc, Hcc]. In nD, the list will contain ``(n**2 + n) / 2`` arrays.

Fcopyr   r$   +order='xy' is only supported for 2D images.r%   unrecognized order: c              3   *   #    U  H	  oS :  v   M     g7f)r   N ).0ss     r!   	<genexpr>0_hessian_matrix_with_gaussian.<locals>.<genexpr>   s     -u!Aus      d   r   c              3   .   >#    U  H
  nTU-  v   M     g 7f)Nr;   )r<   r=   sq1_2s     r!   r>   r?      s     2EqEs   )r)   r   r   truncatec              3   R   >#    U  H  nS /U-  S/-   S /TU-
  S-
  -  -   v   M     g7f)r   r   Nr;   )r<   dr   s     r!   r>   r?      s1     MAA37aS=A3$(Q,#77s   $'r0   )r   r	   dtypeastyper   r*   r+   r,   allmathsqrtr-   dict	functoolspartialr   gaussian_filterr   r/   r   )r   r)   r   r   r0   float_dtyperD   sigma_scaledcommon_kwargs	gaussian_ordersrF   	gradientsaxesax0ax1H_elemsr   rC   s                    @@r!   _hessian_matrix_with_gaussianr[      s   P E'4KLL5L1EzzA~%4-FGGL /w788	{{55::% -u---q3H		!E2E22L|TUM!!#"5"5GGI ::D
 MtMMF<A$KHKq5q	2KIH ;D}~ 6dA>>HC 	).4>   N Is   FF"c           	         [        U 5      n [        U R                  5      nU R                  USS9n U R                  S:  a  US:X  a  [        S5      eUS;  a  [        SU 35      eUc  Sn[        S[        SS	9  U(       a  [        XX#US
9$ [        XX#S9n[        R                  " U5      n[        U R                  5      n	US:X  a  [        U	5      n	[        U	S5       V
Vs/ s H  u  p[        R                  " X   US9PM     nn
nU$ s  snn
f )a	
  Compute the Hessian matrix.

In 2D, the Hessian matrix is defined as::

    H = [Hrr Hrc]
        [Hrc Hcc]

which is computed by convolving the image with the second derivatives
of the Gaussian kernel in the respective r- and c-directions.

The implementation here also supports n-dimensional data.

Parameters
----------
image : ndarray
    Input image.
sigma : float
    Standard deviation used for the Gaussian kernel, which is used as
    weighting function for the auto-correlation matrix.
mode : {'constant', 'reflect', 'wrap', 'nearest', 'mirror'}, optional
    How to handle values outside the image borders.
cval : float, optional
    Used in conjunction with mode 'constant', the value outside
    the image boundaries.
order : {'rc', 'xy'}, optional
    For 2D images, this parameter allows for the use of reverse or forward
    order of the image axes in gradient computation. 'rc' indicates the use
    of the first axis initially (Hrr, Hrc, Hcc), whilst 'xy' indicates the
    usage of the last axis initially (Hxx, Hxy, Hyy). Images with higher
    dimension must always use 'rc' order.
use_gaussian_derivatives : boolean, optional
    Indicates whether the Hessian is computed by convolving with Gaussian
    derivatives, or by a simple finite-difference operation.

Returns
-------
H_elems : list of ndarray
    Upper-diagonal elements of the hessian matrix for each pixel in the
    input image. In 2D, this will be a three element list containing [Hrr,
    Hrc, Hcc]. In nD, the list will contain ``(n**2 + n) / 2`` arrays.


Notes
-----
The distributive property of derivatives and convolutions allows us to
restate the derivative of an image, I, smoothed with a Gaussian kernel, G,
as the convolution of the image with the derivative of G.

.. math::

    \frac{\partial }{\partial x_i}(I * G) =
    I * \left( \frac{\partial }{\partial x_i} G \right)

When ``use_gaussian_derivatives`` is ``True``, this property is used to
compute the second order derivatives that make up the Hessian matrix.

When ``use_gaussian_derivatives`` is ``False``, simple finite differences
on a Gaussian-smoothed image are used instead.

Examples
--------
>>> from skimage.feature import hessian_matrix
>>> square = np.zeros((5, 5))
>>> square[2, 2] = 4
>>> Hrr, Hrc, Hcc = hessian_matrix(square, sigma=0.1, order='rc',
...                                use_gaussian_derivatives=False)
>>> Hrc
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  1.,  0., -1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0., -1.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

Fr6   r   r$   r8   r%   r9   zuse_gaussian_derivatives currently defaults to False, but will change to True in a future version. Please specify this argument explicitly to maintain the current behavior)category
stacklevel)r)   r   r   r0   r(   r   )r   r	   rH   rI   r   r*   r   FutureWarningr[   r   r+   gradientr   r/   r   )r   r)   r   r   r0   use_gaussian_derivativesrQ   gaussian_filteredrV   rW   rX   rY   rZ   s                r!   hessian_matrixrd      s"   \ E'4KLL5L1EzzA~%4-FGGL /w788'#( C #	
  ,TE
 	
 !$J-.ID}~ 6dA>>HC 	IN->   N	s   !#D	Tc                 H   [        U 5      n [        U R                  5      nU R                  USS9n U R                  S:X  a1  U(       a*  [        U 5      n[        R                  " [        XA5      5      $ [        [        XSS95      n[        R                  R                  U5      $ )a  Compute the approximate Hessian Determinant over an image.

The 2D approximate method uses box filters over integral images to
compute the approximate Hessian Determinant.

Parameters
----------
image : ndarray
    The image over which to compute the Hessian Determinant.
sigma : float, optional
    Standard deviation of the Gaussian kernel used for the Hessian
    matrix.
approximate : bool, optional
    If ``True`` and the image is 2D, use a much faster approximate
    computation. This argument has no effect on 3D and higher images.

Returns
-------
out : array
    The array of the Determinant of Hessians.

References
----------
.. [1] Herbert Bay, Andreas Ess, Tinne Tuytelaars, Luc Van Gool,
       "SURF: Speeded Up Robust Features"
       ftp://ftp.vision.ee.ethz.ch/publications/articles/eth_biwi_00517.pdf

Notes
-----
For 2D images when ``approximate=True``, the running time of this method
only depends on size of the image. It is independent of `sigma` as one
would expect. The downside is that the result for `sigma` less than `3`
is not accurate, i.e., not similar to the result obtained if someone
computed the Hessian and took its determinant.
Fr6   r   )rb   )r   r	   rH   rI   r   r   r+   arrayr   _symmetric_imagerd   linalgdet)r   r)   approximaterQ   integralhessian_mat_arrays         r!   hessian_matrix_detrm   U  s    H E'4KLL5L1EzzQ;!%(xx+H<==,5%H
 yy}}.//    c                    [        U 5      S:X  a~  U u  pn[        R                  " S/UR                  Q7UR                  5      nX-   S-  USS& [        R
                  " US-  X-
  S-  S-  -   5      nUS==   U-  ss'   US==   U-  ss'   U$ [        U 5      n[        R                  R                  U5      SSSS24   n[        [        UR                  S-
  5      5      n[        R                  " XDR                  S-
  4U-   5      $ )a  Compute eigenvalues from the upper-diagonal entries of a symmetric
matrix.

Parameters
----------
S_elems : list of ndarray
    The upper-diagonal elements of the matrix, as returned by
    `hessian_matrix` or `structure_tensor`.

Returns
-------
eigs : ndarray
    The eigenvalues of the matrix, in decreasing order. The eigenvalues are
    the leading dimension. That is, ``eigs[i, j, k]`` contains the
    ith-largest eigenvalue at position (j, k).
   r   Nr   r   .)r.   r+   emptyshaperH   rL   rg   rh   eigvalshr-   r   r   	transpose)S_elemsM00M01M11eigshsqrtdetmatricesleading_axess           r!   _symmetric_compute_eigenvaluesr~     s    $ 7|q#xxSYY39/Q7736ci1_$::;Q8Q8#G,yy!!(+C2I6U499q=12||D99q="2\"ABBrn   c                 &   U S   n[         R                  " UR                  UR                  UR                  4-   U S   R                  S9n[        [        [        UR                  5      S5      5       H  u  nu  pEX   USXE4'   X   USXT4'   M     U$ )a  Convert the upper-diagonal elements of a matrix to the full
symmetric matrix.

Parameters
----------
S_elems : list of array
    The upper-diagonal elements of the matrix, as returned by
    `hessian_matrix` or `structure_tensor`.

Returns
-------
image : array
    An array of shape ``(M, N[, ...], image.ndim, image.ndim)``,
    containing the matrix corresponding to each coordinate.
r   rH   r   .)r+   zerosrs   r   rH   	enumerater   r   )rv   r   symmetric_imageidxrowcols         r!   rg   rg     s      AJEhhuzz5::..gaj6F6FO %%eEJJ&7;Zc *1S&)0S&	
 rn   c                     [        U 5      $ )a}  Compute eigenvalues of structure tensor.

Parameters
----------
A_elems : list of ndarray
    The upper-diagonal elements of the structure tensor, as returned
    by `structure_tensor`.

Returns
-------
ndarray
    The eigenvalues of the structure tensor, in decreasing order. The
    eigenvalues are the leading dimension. That is, the coordinate
    [i, j, k] corresponds to the ith-largest eigenvalue at position (j, k).

Examples
--------
>>> from skimage.feature import structure_tensor
>>> from skimage.feature import structure_tensor_eigenvalues
>>> square = np.zeros((5, 5))
>>> square[2, 2] = 1
>>> A_elems = structure_tensor(square, sigma=0.1, order='rc')
>>> structure_tensor_eigenvalues(A_elems)[0]
array([[0., 0., 0., 0., 0.],
       [0., 2., 4., 2., 0.],
       [0., 4., 0., 4., 0.],
       [0., 2., 4., 2., 0.],
       [0., 0., 0., 0., 0.]])

See also
--------
structure_tensor
r~   )r3   s    r!   structure_tensor_eigenvaluesr     s    D *'22rn   c                     [        U 5      $ )ar  Compute eigenvalues of Hessian matrix.

Parameters
----------
H_elems : list of ndarray
    The upper-diagonal elements of the Hessian matrix, as returned
    by `hessian_matrix`.

Returns
-------
eigs : ndarray
    The eigenvalues of the Hessian matrix, in decreasing order. The
    eigenvalues are the leading dimension. That is, ``eigs[i, j, k]``
    contains the ith-largest eigenvalue at position (j, k).

Examples
--------
>>> from skimage.feature import hessian_matrix, hessian_matrix_eigvals
>>> square = np.zeros((5, 5))
>>> square[2, 2] = 4
>>> H_elems = hessian_matrix(square, sigma=0.1, order='rc',
...                          use_gaussian_derivatives=False)
>>> hessian_matrix_eigvals(H_elems)[0]
array([[ 0.,  0.,  2.,  0.,  0.],
       [ 0.,  1.,  0.,  1.,  0.],
       [ 2.,  0., -2.,  0.,  2.],
       [ 0.,  1.,  0.,  1.,  0.],
       [ 0.,  0.,  2.,  0.,  0.]])
r   )rZ   s    r!   hessian_matrix_eigvalsr     s    < *'22rn   c           	          [        U UUUSSS9n[        U5      u  pV[        R                  " SSS9   S[        R                  -  [        R
                  " Xe-   Xe-
  -  5      -  sSSS5        $ ! , (       d  f       g= f)a  Compute the shape index.

The shape index, as defined by Koenderink & van Doorn [1]_, is a
single valued measure of local curvature, assuming the image as a 3D plane
with intensities representing heights.

It is derived from the eigenvalues of the Hessian, and its
value ranges from -1 to 1 (and is undefined (=NaN) in *flat* regions),
with following ranges representing following shapes:

.. table:: Ranges of the shape index and corresponding shapes.

  ===================  =============
  Interval (s in ...)  Shape
  ===================  =============
  [  -1, -7/8)         Spherical cup
  [-7/8, -5/8)         Through
  [-5/8, -3/8)         Rut
  [-3/8, -1/8)         Saddle rut
  [-1/8, +1/8)         Saddle
  [+1/8, +3/8)         Saddle ridge
  [+3/8, +5/8)         Ridge
  [+5/8, +7/8)         Dome
  [+7/8,   +1]         Spherical cap
  ===================  =============

Parameters
----------
image : (M, N) ndarray
    Input image.
sigma : float, optional
    Standard deviation used for the Gaussian kernel, which is used for
    smoothing the input data before Hessian eigen value calculation.
mode : {'constant', 'reflect', 'wrap', 'nearest', 'mirror'}, optional
    How to handle values outside the image borders
cval : float, optional
    Used in conjunction with mode 'constant', the value outside
    the image boundaries.

Returns
-------
s : ndarray
    Shape index

References
----------
.. [1] Koenderink, J. J. & van Doorn, A. J.,
       "Surface shape and curvature scales",
       Image and Vision Computing, 1992, 10, 557-564.
       :DOI:`10.1016/0262-8856(92)90076-F`

Examples
--------
>>> from skimage.feature import shape_index
>>> square = np.zeros((5, 5))
>>> square[2, 2] = 4
>>> s = shape_index(square, sigma=0.1)
>>> s
array([[ nan,  nan, -0.5,  nan,  nan],
       [ nan, -0. ,  nan, -0. ,  nan],
       [-0.5,  nan, -1. ,  nan, -0.5],
       [ nan, -0. ,  nan, -0. ,  nan],
       [ nan,  nan, -0.5,  nan,  nan]])
r&   F)r)   r   r   r0   rb   ignore)divideinvalidg       @N)rd   r   r+   errstatepiarctan)r   r)   r   r   Hl1l2s          r!   shape_indexr   
  sm    D 	!&	A $A&FB 
Hh	7beeryy"'bg)>?? 
8	7	7s   1A,,
A:c                 ,   [        U R                  5      nU R                  USS9n [        XUS9u  pE[        XQUS9u  pg[        XAUS9u  pXtS-  -  XS-  -  -   SU-  U-  U-  -
  n
US-  US-  -   n[        R
                  " XS9nUS:g  nX   X   -  X'   U$ )aG  Compute Kitchen and Rosenfeld corner measure response image.

The corner measure is calculated as follows::

    (imxx * imy**2 + imyy * imx**2 - 2 * imxy * imx * imy)
        / (imx**2 + imy**2)

Where imx and imy are the first and imxx, imxy, imyy the second
derivatives.

Parameters
----------
image : (M, N) ndarray
    Input image.
mode : {'constant', 'reflect', 'wrap', 'nearest', 'mirror'}, optional
    How to handle values outside the image borders.
cval : float, optional
    Used in conjunction with mode 'constant', the value outside
    the image boundaries.

Returns
-------
response : ndarray
    Kitchen and Rosenfeld response image.

References
----------
.. [1] Kitchen, L., & Rosenfeld, A. (1982). Gray-level corner detection.
       Pattern recognition letters, 1(2), 95-102.
       :DOI:`10.1016/0167-8655(82)90020-4`
Fr6   r'   r   r   r   )r	   rH   rI   r"   r+   
zeros_like)r   r   r   rQ   imyimximxyimxximyyimyx	numeratordenominatorresponsemasks                 r!   corner_kitchen_rosenfeldr   [  s    B (4KLL5L1E#E4@HC%c4@JD%c4@JDAvAv-D30DDIq&36/K}}U6H!D_{'88HNOrn   c                 t    [        XSS9u  pVnXW-  US-  -
  nXW-   n	US:X  a  XU	S-  -  -
  n
U
$ SU-  X-   -  n
U
$ )a  Compute Harris corner measure response image.

This corner detector uses information from the auto-correlation matrix A::

    A = [(imx**2)   (imx*imy)] = [Axx Axy]
        [(imx*imy)   (imy**2)]   [Axy Ayy]

Where imx and imy are first derivatives, averaged with a gaussian filter.
The corner measure is then defined as::

    det(A) - k * trace(A)**2

or::

    2 * det(A) / (trace(A) + eps)

Parameters
----------
image : (M, N) ndarray
    Input image.
method : {'k', 'eps'}, optional
    Method to compute the response image from the auto-correlation matrix.
k : float, optional
    Sensitivity factor to separate corners from edges, typically in range
    `[0, 0.2]`. Small values of k result in detection of sharp corners.
eps : float, optional
    Normalisation factor (Noble's corner measure).
sigma : float, optional
    Standard deviation used for the Gaussian kernel, which is used as
    weighting function for the auto-correlation matrix.

Returns
-------
response : ndarray
    Harris response image.

References
----------
.. [1] https://en.wikipedia.org/wiki/Corner_detection

Examples
--------
>>> from skimage.feature import corner_harris, corner_peaks
>>> square = np.zeros([10, 10])
>>> square[2:8, 2:8] = 1
>>> square.astype(int)
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
>>> corner_peaks(corner_harris(square), min_distance=1)
array([[2, 2],
       [2, 7],
       [7, 2],
       [7, 7]])

r&   rG   r   k)r4   )r   methodr   epsr)   ArrArcAccdetAtraceAr   s              r!   corner_harrisr     sc    B %U>MCc 9sAvDYF}fai-' O t8v|,Orn   c                 x    [        XSS9u  p#nX$-   [        R                  " X$-
  S-  SUS-  -  -   5      -
  S-  nU$ )a  Compute Shi-Tomasi (Kanade-Tomasi) corner measure response image.

This corner detector uses information from the auto-correlation matrix A::

    A = [(imx**2)   (imx*imy)] = [Axx Axy]
        [(imx*imy)   (imy**2)]   [Axy Ayy]

Where imx and imy are first derivatives, averaged with a gaussian filter.
The corner measure is then defined as the smaller eigenvalue of A::

    ((Axx + Ayy) - sqrt((Axx - Ayy)**2 + 4 * Axy**2)) / 2

Parameters
----------
image : (M, N) ndarray
    Input image.
sigma : float, optional
    Standard deviation used for the Gaussian kernel, which is used as
    weighting function for the auto-correlation matrix.

Returns
-------
response : ndarray
    Shi-Tomasi response image.

References
----------
.. [1] https://en.wikipedia.org/wiki/Corner_detection

Examples
--------
>>> from skimage.feature import corner_shi_tomasi, corner_peaks
>>> square = np.zeros([10, 10])
>>> square[2:8, 2:8] = 1
>>> square.astype(int)
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
>>> corner_peaks(corner_shi_tomasi(square), min_distance=1)
array([[2, 2],
       [2, 7],
       [7, 2],
       [7, 7]])

r&   rG   r      )r4   r+   rL   )r   r)   r   r   r   r   s         r!   corner_shi_tomasir     sJ    l %U>MCc bggsyQ&6S!V&CDDIHOrn   c                     [        XSS9u  p#nX$-  US-  -
  nX$-   n[        R                  " XR                  S9n[        R                  " U5      nUS:g  n	XY   Xi   -  Xy'   SXY   -  Xi   S-  -  X'   Xx4$ )u  Compute Foerstner corner measure response image.

This corner detector uses information from the auto-correlation matrix A::

    A = [(imx**2)   (imx*imy)] = [Axx Axy]
        [(imx*imy)   (imy**2)]   [Axy Ayy]

Where imx and imy are first derivatives, averaged with a gaussian filter.
The corner measure is then defined as::

    w = det(A) / trace(A)           (size of error ellipse)
    q = 4 * det(A) / trace(A)**2    (roundness of error ellipse)

Parameters
----------
image : (M, N) ndarray
    Input image.
sigma : float, optional
    Standard deviation used for the Gaussian kernel, which is used as
    weighting function for the auto-correlation matrix.

Returns
-------
w : ndarray
    Error ellipse sizes.
q : ndarray
    Roundness of error ellipse.

References
----------
.. [1] Förstner, W., & Gülch, E. (1987, June). A fast operator for
       detection and precise location of distinct points, corners and
       centres of circular features. In Proc. ISPRS intercommission
       conference on fast processing of photogrammetric data (pp. 281-305).
       https://cseweb.ucsd.edu/classes/sp02/cse252/foerstner/foerstner.pdf
.. [2] https://en.wikipedia.org/wiki/Corner_detection

Examples
--------
>>> from skimage.feature import corner_foerstner, corner_peaks
>>> square = np.zeros([10, 10])
>>> square[2:8, 2:8] = 1
>>> square.astype(int)
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
>>> w, q = corner_foerstner(square)
>>> accuracy_thresh = 0.5
>>> roundness_thresh = 0.3
>>> foerstner = (q > roundness_thresh) * (w > accuracy_thresh) * w
>>> corner_peaks(foerstner, min_distance=1)
array([[2, 2],
       [2, 7],
       [7, 2],
       [7, 7]])

r&   rG   r   r   r   r   )r4   r+   r   rH   )
r   r)   r   r   r   r   r   wqr   s
             r!   corner_foerstnerr     s    D %U>MCc 9sAvDYF
e::.A
aAQ;Dj6<'AG$*nv|q00AG4Krn   c                 `    [        U 5      n [        R                  " U 5      n [        XU5      nU$ )a  Extract FAST corners for a given image.

Parameters
----------
image : (M, N) ndarray
    Input image.
n : int, optional
    Minimum number of consecutive pixels out of 16 pixels on the circle
    that should all be either brighter or darker w.r.t testpixel.
    A point c on the circle is darker w.r.t test pixel p if
    `Ic < Ip - threshold` and brighter if `Ic > Ip + threshold`. Also
    stands for the n in `FAST-n` corner detector.
threshold : float, optional
    Threshold used in deciding whether the pixels on the circle are
    brighter, darker or similar w.r.t. the test pixel. Decrease the
    threshold when more corners are desired and vice-versa.

Returns
-------
response : ndarray
    FAST corner response image.

References
----------
.. [1] Rosten, E., & Drummond, T. (2006, May). Machine learning for
       high-speed corner detection. In European conference on computer
       vision (pp. 430-443). Springer, Berlin, Heidelberg.
       :DOI:`10.1007/11744023_34`
       http://www.edwardrosten.com/work/rosten_2006_machine.pdf
.. [2] Wikipedia, "Features from accelerated segment test",
       https://en.wikipedia.org/wiki/Features_from_accelerated_segment_test

Examples
--------
>>> from skimage.feature import corner_fast, corner_peaks
>>> square = np.zeros((12, 12))
>>> square[3:9, 3:9] = 1
>>> square.astype(int)
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
>>> corner_peaks(corner_fast(square, 9), min_distance=1)
array([[3, 3],
       [3, 8],
       [8, 3],
       [8, 8]])

)r   r+   ascontiguousarrayr   )r   n	thresholdr   s       r!   corner_fastr   p  s0    t (.E  'EEi0HOrn   c                 	   US-
  S-  n[        U R                  5      nU R                  USS9n [        R                  " XSSS9n [        X-   5      n[        R                  " SUS	9n[        R                  " SUS	9n[        R                  " S
US	9n[        R                  " S
US	9n	US-  S-
  n
[        R                  R                  SU-
  X5      n[        R                  R                  X:U
5      n[        R                  U* US-   2U* US-   24   u  p[        R                  " XS	9n[        U5       GHC  u  nu  nnUU-
  S-
  nUU-   S-   nUU-
  S-
  nUU-   S-   nU UU2UU24   n[        USSS9u  nnUU-  SS2SS24   nUU-  SS2SS24   nUU-  SS2SS24   n[        R                  " U5      n[        R                  " U5      n[        R                  " U5      n[        R                  " UU-  5      n [        R                  " UU-  5      n![        R                  " UU-  5      n"[        R                  " UU-  5      n#[        R                  " UU-  5      n$[        R                  " UU-  5      n%UUS'   U* =US'   US'   UUS'   UUS'   U=US'   US'   UUS'   U!U"-
  U$U#-
  4USS& U%U"-   U U#-   4U	SS&  [        R                  R!                  Xh5      n&[        R                  R!                  Xy5      n'UU&S   -
  n(UU&S   -
  n)UU'S   -
  n*UU'S   -
  n+U)U)-  n,U)U(-  n-U(U(-  n.U+U+-  n/U+U*-  n0U*U*-  n1[        R                  " UU.-  SU-  U--  -
  UU,-  -   5      n2[        R                  " UU1-  SU-  U0-  -   UU/-  -   5      n3U2[        R&                  " S5      :  a+  U3[        R&                  " S5      :  a  [        R$                  n4OU2S:X  a  [        R(                  n4OU3U2-  n4[+        U4U:  5      [+        U4U:  5      -
  n5U5S:X  a  UU&S   -   UU&S   -   4UUSS24'   GM  U5S:X  a*  [        R$                  [        R$                  4UUSS24'   GM#  U5S:X  d  GM,  UU'S   -   UU'S   -   4UUSS24'   GMF     X-  nU$ ! [        R                  R"                   a,    [        R$                  [        R$                  4UUSS24'    GM  f = f)u  Determine subpixel position of corners.

A statistical test decides whether the corner is defined as the
intersection of two edges or a single peak. Depending on the classification
result, the subpixel corner location is determined based on the local
covariance of the grey-values. If the significance level for either
statistical test is not sufficient, the corner cannot be classified, and
the output subpixel position is set to NaN.

Parameters
----------
image : (M, N) ndarray
    Input image.
corners : (K, 2) ndarray
    Corner coordinates `(row, col)`.
window_size : int, optional
    Search window size for subpixel estimation.
alpha : float, optional
    Significance level for corner classification.

Returns
-------
positions : (K, 2) ndarray
    Subpixel corner positions. NaN for "not classified" corners.

References
----------
.. [1] Förstner, W., & Gülch, E. (1987, June). A fast operator for
       detection and precise location of distinct points, corners and
       centres of circular features. In Proc. ISPRS intercommission
       conference on fast processing of photogrammetric data (pp. 281-305).
       https://cseweb.ucsd.edu/classes/sp02/cse252/foerstner/foerstner.pdf
.. [2] https://en.wikipedia.org/wiki/Corner_detection

Examples
--------
>>> from skimage.feature import corner_harris, corner_peaks, corner_subpix
>>> img = np.zeros((10, 10))
>>> img[:5, :5] = 1
>>> img[5:, 5:] = 1
>>> img.astype(int)
array([[1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
       [0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
       [0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
       [0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
       [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]])
>>> coords = corner_peaks(corner_harris(img), min_distance=2)
>>> coords_subpix = corner_subpix(img, coords, window_size=7)
>>> coords_subpix
array([[4.5, 4.5]])

r   r   Fr6   constantr   )	pad_widthr   constant_values)r   r   r   )r   r'   rq   )r   r   )r   r   )r   r   )r   r   N)r	   rH   rI   r+   padr
   r   r   fisfmgridr   r   r"   sumrh   solveLinAlgErrornanspacinginfint)6r   cornerswindow_sizealphawextrQ   N_dotN_edgeb_dotb_edge
redundancy
t_crit_dott_crit_edgeyxcorners_subpixr   y0x0minymaxyminxmaxxwindowwinywinx	winx_winx	winx_winy	winy_winyAxxAxyAyybxx_xbxx_ybxy_xbxy_ybyy_xbyy_yest_dotest_edgery_dotrx_dotry_edgerx_edgerxx_dotrxy_dotryy_dotrxx_edgerxy_edgeryy_edgevar_dotvar_edgetcorner_classs6                                                         r!   corner_subpixr     s   x !O!D'4KLL5L1EFF5z1ME '.)G HHV;/EXXfK0FHHT-EXXd+.F a!#JQY
?J''++e<K 88TED1H$tedQh&667DA]]7>N )8BDy1}Dy1}Dy1}Dy1}tDy$t)+,)&zJ
d D[!B$"*-	D[!B$"*-	D[!B$"*-	 ffYffYffY y1}%y1}%y1}%y1}%y1}%y1}% d%(D(deDkdt&))tvd|t5=%%-/aEM55=0q		iiooe3Gyyv6H WQZWQZhqk/hqk/6/6/6/W$W$W$ &&!i-'"99I<OO
 66 1y=8#;;i(>RR

 RZZ]"x"**Q-'?A\A7"A 1{?+c!j..AA2#%
?BO#CN1a4 Q#%66266>N1a4 Q#%#3R(1+5E#EN1a4 q *v Na yy$$ 	#%66266>N1a4 	s   ;>R  AS
	S
)num_peaks_per_labelp_normc	                0   [         R                  " U5      (       a  Sn[        U UUUU[         R                  UUU	S9	n[	        U5      (       a  [
        R                  " U5      n[        5       n[        U5       H>  u  pX;  d  M  UR                  XU
S9nUR                  U5        UR                  U5        M@     [         R                  " U[        U5      SS9SU nU(       a  U$ [         R                  " U [        S9nSU[        UR                   5      '   U$ )a  Find peaks in corner measure response image.

This differs from `skimage.feature.peak_local_max` in that it suppresses
multiple connected peaks with the same accumulator value.

Parameters
----------
image : (M, N) ndarray
    Input image.
min_distance : int, optional
    The minimal allowed distance separating peaks.
* : *
    See :py:meth:`skimage.feature.peak_local_max`.
p_norm : float
    Which Minkowski p-norm to use. Should be in the range [1, inf].
    A finite large p may cause a ValueError if overflow can occur.
    ``inf`` corresponds to the Chebyshev distance and 2 to the
    Euclidean distance.

Returns
-------
output : ndarray or ndarray of bools

    * If `indices = True`  : (row, column, ...) coordinates of peaks.
    * If `indices = False` : Boolean array shaped like `image`, with peaks
      represented by True values.

See also
--------
skimage.feature.peak_local_max

Notes
-----
.. versionchanged:: 0.18
    The default value of `threshold_rel` has changed to None, which
    corresponds to letting `skimage.feature.peak_local_max` decide on the
    default. This is equivalent to `threshold_rel=0`.

The `num_peaks` limit is applied before suppression of connected peaks.
To limit the number of peaks after suppression, set `num_peaks=np.inf` and
post-process the output of this function.

Examples
--------
>>> from skimage.feature import peak_local_max
>>> response = np.zeros((5, 5))
>>> response[2:4, 2:4] = 1
>>> response
array([[0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 1., 1., 0.],
       [0., 0., 1., 1., 0.],
       [0., 0., 0., 0., 0.]])
>>> peak_local_max(response)
array([[2, 2],
       [2, 3],
       [3, 2],
       [3, 3]])
>>> corner_peaks(response)
array([[2, 2]])

N)min_distancethreshold_absthreshold_relexclude_border	num_peaks	footprintlabelsr   )rpr   r_   r   T)r+   isinfr   r   r.   r   cKDTreesetr   query_ball_pointremoveupdatedeleter-   r   boolT)r   r   r  r  r  indicesr  r  r  r   r   coordstreerejected_peaks_indicesr   point
candidatespeakss                     r!   corner_peaksr  f  s    X 
xx		 !##%&&/
F 6{{v&!$#F+JC0!225F2S
!!#&&--j9	 , 65)?#@qI*9UMM%t,E!E%/Lrn   c                     [        U 5      n [        U R                  5      nU R                  USS9n [	        [
        R                  " U 5      U5      $ )a  Compute Moravec corner measure response image.

This is one of the simplest corner detectors and is comparatively fast but
has several limitations (e.g. not rotation invariant).

Parameters
----------
image : (M, N) ndarray
    Input image.
window_size : int, optional
    Window size.

Returns
-------
response : ndarray
    Moravec response image.

References
----------
.. [1] https://en.wikipedia.org/wiki/Corner_detection

Examples
--------
>>> from skimage.feature import corner_moravec
>>> square = np.zeros([7, 7])
>>> square[3, 3] = 1
>>> square.astype(int)
array([[0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 1, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0]])
>>> corner_moravec(square).astype(int)
array([[0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 1, 1, 1, 0, 0],
       [0, 0, 1, 2, 1, 0, 0],
       [0, 0, 1, 1, 1, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0]])
Fr6   )r   r	   rH   rI   r   r+   r   )r   r   rQ   s      r!   corner_moravecr    sG    X E'4KLL5L1E2//6DDrn   c                 0    [        U 5      n [        XU5      $ )a*  Compute the orientation of corners.

The orientation of corners is computed using the first order central moment
i.e. the center of mass approach. The corner orientation is the angle of
the vector from the corner coordinate to the intensity centroid in the
local neighborhood around the corner calculated using first order central
moment.

Parameters
----------
image : (M, N) array
    Input grayscale image.
corners : (K, 2) array
    Corner coordinates as ``(row, col)``.
mask : 2D array
    Mask defining the local neighborhood of the corner used for the
    calculation of the central moment.

Returns
-------
orientations : (K, 1) array
    Orientations of corners in the range [-pi, pi].

References
----------
.. [1] Ethan Rublee, Vincent Rabaud, Kurt Konolige and Gary Bradski
      "ORB : An efficient alternative to SIFT and SURF"
      http://www.vision.cs.chubu.ac.jp/CV-R/pdf/Rublee_iccv2011.pdf
.. [2] Paul L. Rosin, "Measuring Corner Properties"
      http://users.cs.cf.ac.uk/Paul.Rosin/corner2.pdf

Examples
--------
>>> from skimage.morphology import octagon
>>> from skimage.feature import (corner_fast, corner_peaks,
...                              corner_orientations)
>>> square = np.zeros((12, 12))
>>> square[3:9, 3:9] = 1
>>> square.astype(int)
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
>>> corners = corner_peaks(corner_fast(square, 9), min_distance=1)
>>> corners
array([[3, 3],
       [3, 8],
       [8, 3],
       [8, 8]])
>>> orientations = corner_orientations(square, corners, octagon(3, 2))
>>> np.rad2deg(orientations)
array([  45.,  135.,  -45., -135.])

)r   r   )r   r   r   s      r!   corner_orientationsr    s    ~ (.E55rn   )r   r   )r   r   r   r&   )r   reflectr   r&   )r   r   r   r&   N)r   T)r   r   r   )r   g?gư>r   )r   )   g333333?)   gGz?)3rN   rK   	itertoolsr   numpyr+   scipyr   r   r   r   _shared.filtersr   _shared.utilsr	   r
   r   	transformr   utilr   _hessian_det_appxr   	corner_cyr   r   r   peakr   r   r   r"   r4   r[   rd   rm   r~   rg   r   r   r   r   r   r   r   r   r   r   r  r  r  r;   rn   r!   <module>r+     s      3      & D D &  2 J J   J6UpXx SWqh.0bCD8"3J3BN@b0fM`;|Qh>Brn ffp 66pf/Ed@6rn   