Ë
    ÿ[;jâu  ã                   ó¨   — d dl Z d dlZd dlmZ ddlmZmZ ddl	m
Z
mZ ddlmZ ddlmZ ddlmZ dd	lmZmZmZ d
„ Zd„ Zd„ Zd„ Z G d„ dee
«      Zy)é    Né   )Úcheck_nDÚ_supported_float_type)ÚDescriptorExtractorÚFeatureDetector)Úgaussian)Úrescale)Úimg_as_floaté   )Ú
_local_maxÚ_ori_distancesÚ_update_histogramc                 ó2   — | |z   }| |z  ||z  z
  }||z  |z  S )z5Compute edgeness (eq. 18 of Otero et. al. IPOL paper)© )ÚhxxÚhyyÚhxyÚtraceÚdeterminants        ú]G:\00. PROJECTS\API\Inventory\templateJSON\kerjaOCR\Lib\site-packages\skimage/feature/sift.pyÚ	_edgenessr      s,   € à�#‰I€EØ˜‘)˜c C™iÑ'€KØ�E‰M˜[Ñ(Ð(ó    c                 óÒ   — |d   }|d   }|d   }| |dz   ||f   | |dz
  ||f   z
  }|dz  }| ||dz   |f   | ||dz
  |f   z
  }|dz  }| |||dz   f   | |||dz
  f   z
  }|dz  }|||fS )zùGradient of a 3D volume at the provided `positions`.

    For SIFT we only need the gradient at specific positions and do not need
    the gradient at the edge positions, so can just use this simple
    implementation instead of numpy.gradient.
    ©.r   ©.r   ©.r   r   ç      à?r   )ÚvolÚ	positionsÚp0Úp1Úp2Úg0Úg1Úg2s           r   Ú_sparse_gradientr&      sÁ   € ð 
�6Ñ	€BØ	�6Ñ	€BØ	�6Ñ	€BØ	ˆR�!‰V�R˜ˆ^Ñ	˜s 2¨¡6¨2¨r >Ñ2Ñ	2€BØˆ#�I€BØ	ˆR��a‘˜ˆ^Ñ	˜s 2 r¨A¡v¨r >Ñ2Ñ	2€BØˆ#�I€BØ	ˆR��R˜!‘Vˆ^Ñ	˜s 2 r¨2°©6 >Ñ2Ñ	2€BØˆ#�I€BØˆr�2ˆ:Ðr   c                 óV  — |d   }|d   }|d   }d| |||f   z  }| |dz
  ||f   | |dz   ||f   z   |z
  }| ||dz
  |f   | ||dz   |f   z   |z
  }| |||dz
  f   | |||dz   f   z   |z
  }d| |dz   |dz   |f   | |dz
  |dz   |f   z
  | |dz   |dz
  |f   z
  | |dz
  |dz
  |f   z   z  }	d| |dz   ||dz   f   | |dz   ||dz
  f   z
  | |dz
  ||dz
  f   z   | |dz
  ||dz   f   z
  z  }
d| ||dz   |dz   f   | ||dz   |dz
  f   z
  | ||dz
  |dz
  f   z   | ||dz
  |dz   f   z
  z  }||||	|
|fS )z�Compute the non-redundant 3D Hessian terms at the requested positions.

    Source: "Anatomy of the SIFT Method"  p.380 (13)
    r   r   r   r   r   g      Ð?r   )Údr   r    r!   r"   Útwo_d0Úh00Úh11Úh22Úh01Úh02Úh12s               r   Ú_hessianr0   (   s;  € ð
 
�6Ñ	€BØ	�6Ñ	€BØ	�6Ñ	€BØ��2�r˜2�:‘Ñ€Fà
ˆB�‰F�B˜ˆNÑ
˜a  Q¡¨¨B Ñ/Ñ
/°&Ñ
8€CØ
ˆB��Q‘˜ˆNÑ
˜a  B¨¡F¨B Ñ/Ñ
/°&Ñ
8€CØ
ˆB��B˜‘FˆNÑ
˜a  B¨¨Q© Ñ/Ñ
/°&Ñ
8€CØ
Ø	ˆ"ˆq‰&�"�q‘&˜"Ð
ÑØ
ˆB�‰F�B˜‘F˜BÐÑ
ñ	 à
ˆB�‰F�B˜‘F˜BÐÑ
ñ	 ð ˆB�‰F�B˜‘F˜BÐÑ
ñ	 ñ€Cð Ø	ˆ"ˆq‰&�"�b˜1‘fÐ
ÑØ
ˆB�‰F�B˜˜Q™ÐÑ
ñ	 à
ˆB�‰F�B˜˜Q™ÐÑ
ñ	 ð ˆB�‰F�B˜˜Q™ÐÑ
ñ	 ñ€Cð Ø	ˆ"ˆb�1‰f�b˜1‘fÐ
ÑØ
ˆB��Q‘˜˜Q™ÐÑ
ñ	 à
ˆB��Q‘˜˜Q™ÐÑ
ñ	 ð ˆB��Q‘˜˜Q™ÐÑ
ñ	 ñ€Cð ��c˜3  SÐ)Ð)r   c                 óÖ  — |\  }}}}}}| \  }}	}
||z  |z  }|||z  |z  z  }|||z  |z  z  }|d|z  |z  |z  z  }|||z  |z  z  }||z  ||z  z
  |z  }||z  ||z  z
  |z  }||z  ||z  z
  |z  }||z  ||z  z
  |z  }||z  ||z  z
  |z  }||z  ||z  z
  |z  }| |z  ||	z  z
  ||
z  z
  }| |z  ||	z  z
  ||
z  z
  }| |z  ||	z  z
  ||
z  z
  }t        j                  |||fd¬«      S )a2  Compute position refinement offsets from gradient and Hessian.

    This is equivalent to np.linalg.solve(-H, J) where H is the Hessian
    matrix and J is the gradient (Jacobian).

    This analytical solution is adapted from (BSD-licensed) C code by
    Otero et. al (see SIFT docstring References).
    r   éÿÿÿÿ©Úaxis)ÚnpÚstack)ÚgradÚhessr*   r+   r,   r-   r.   r/   r#   r$   r%   ÚdetÚaaÚabÚacÚbbÚbcÚccÚoffset0Úoffset1Úoffset2s                        r   Ú_offsetsrC   J   st  € ð $(Ñ €Cˆˆc�3˜˜SØ�J€BˆˆBØ
�‰)�c‰/€CØˆ3�‰9�s‰?Ñ€CØˆ3�‰9�s‰?Ñ€CØˆ1ˆs‰7�S‰=˜3ÑÑ€CØˆ3�‰9�s‰?Ñ€CØ
�‰)�c˜C‘iÑ
 3Ñ	&€BØ
�‰)�c˜C‘iÑ
 3Ñ	&€BØ
�‰)�c˜C‘iÑ
 3Ñ	&€BØ
�‰)�c˜C‘iÑ
 3Ñ	&€BØ
�‰)�c˜C‘iÑ
 3Ñ	&€BØ
�‰)�c˜C‘iÑ
 3Ñ	&€BØˆc�B‰h˜˜b™Ñ  2¨¡7Ñ*€GØˆc�B‰h˜˜b™Ñ  2¨¡7Ñ*€GØˆc�B‰h˜˜b™Ñ  2¨¡7Ñ*€GÜ�8‰8�W˜g wÐ/°bÔ9Ð9r   c                   óŠ   — e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 	 dd„Zed„ «       Zd„ Zd„ Zd„ Z	d„ Z
d„ Zd	„ Zd
„ Zd„ Zd„ Zd„ Zd„ Zd„ Zy)ÚSIFTu´  SIFT feature detection and descriptor extraction.

    Parameters
    ----------
    upsampling : int, optional
        Prior to the feature detection the image is upscaled by a factor
        of 1 (no upscaling), 2 or 4. Method: Bi-cubic interpolation.
    n_octaves : int, optional
        Maximum number of octaves. With every octave the image size is
        halved and the sigma doubled. The number of octaves will be
        reduced as needed to keep at least 12 pixels along each dimension
        at the smallest scale.
    n_scales : int, optional
        Maximum number of scales in every octave.
    sigma_min : float, optional
        The blur level of the seed image. If upsampling is enabled
        sigma_min is scaled by factor 1/upsampling
    sigma_in : float, optional
        The assumed blur level of the input image.
    c_dog : float, optional
        Threshold to discard low contrast extrema in the DoG. It's final
        value is dependent on n_scales by the relation:
        final_c_dog = (2^(1/n_scales)-1) / (2^(1/3)-1) * c_dog
    c_edge : float, optional
        Threshold to discard extrema that lie in edges. If H is the
        Hessian of an extremum, its "edgeness" is described by
        tr(H)Â²/det(H). If the edgeness is higher than
        (c_edge + 1)Â²/c_edge, the extremum is discarded.
    n_bins : int, optional
        Number of bins in the histogram that describes the gradient
        orientations around keypoint.
    lambda_ori : float, optional
        The window used to find the reference orientation of a keypoint
        has a width of 6 * lambda_ori * sigma and is weighted by a
        standard deviation of 2 * lambda_ori * sigma.
    c_max : float, optional
        The threshold at which a secondary peak in the orientation
        histogram is accepted as orientation
    lambda_descr : float, optional
        The window used to define the descriptor of a keypoint has a width
        of 2 * lambda_descr * sigma * (n_hist+1)/n_hist and is weighted by
        a standard deviation of lambda_descr * sigma.
    n_hist : int, optional
        The window used to define the descriptor of a keypoint consists of
        n_hist * n_hist histograms.
    n_ori : int, optional
        The number of bins in the histograms of the descriptor patch.

    Attributes
    ----------
    delta_min : float
        The sampling distance of the first octave. It's final value is
        1/upsampling.
    float_dtype : type
        The datatype of the image.
    scalespace_sigmas : (n_octaves, n_scales + 3) array
        The sigma value of all scales in all octaves.
    keypoints : (N, 2) array
        Keypoint coordinates as ``(row, col)``.
    positions : (N, 2) array
        Subpixel-precision keypoint coordinates as ``(row, col)``.
    sigmas : (N,) array
        The corresponding sigma (blur) value of a keypoint.
    scales : (N,) array
        The corresponding scale of a keypoint.
    orientations : (N,) array
        The orientations of the gradient around every keypoint.
    octaves : (N,) array
        The corresponding octave of a keypoint.
    descriptors : (N, n_hist*n_hist*n_ori) array
        The descriptors of a keypoint.

    Notes
    -----
    The SIFT algorithm was developed by David Lowe [1]_, [2]_ and later
    patented by the University of British Columbia. Since the patent expired in
    2020 it's free to use. The implementation here closely follows the
    detailed description in [3]_, including use of the same default parameters.

    References
    ----------
    .. [1] D.G. Lowe. "Object recognition from local scale-invariant
           features", Proceedings of the Seventh IEEE International
           Conference on Computer Vision, 1999, vol.2, pp. 1150-1157.
           :DOI:`10.1109/ICCV.1999.790410`

    .. [2] D.G. Lowe. "Distinctive Image Features from Scale-Invariant
           Keypoints", International Journal of Computer Vision, 2004,
           vol. 60, pp. 91â€“110.
           :DOI:`10.1023/B:VISI.0000029664.99615.94`

    .. [3] I. R. Otero and M. Delbracio. "Anatomy of the SIFT Method",
           Image Processing On Line, 4 (2014), pp. 370â€“396.
           :DOI:`10.5201/ipol.2014.82`

    Examples
    --------
    >>> from skimage.feature import SIFT, match_descriptors
    >>> from skimage.data import camera
    >>> from skimage.transform import rotate
    >>> img1 = camera()
    >>> img2 = rotate(camera(), 90)
    >>> detector_extractor1 = SIFT()
    >>> detector_extractor2 = SIFT()
    >>> detector_extractor1.detect_and_extract(img1)
    >>> detector_extractor2.detect_and_extract(img2)
    >>> matches = match_descriptors(detector_extractor1.descriptors,
    ...                             detector_extractor2.descriptors,
    ...                             max_ratio=0.6)
    >>> matches[10:15]
    array([[ 10, 412],
           [ 11, 417],
           [ 12, 407],
           [ 13, 411],
           [ 14, 406]])
    >>> detector_extractor1.keypoints[matches[10:15, 0]]
    array([[ 95, 214],
           [ 97, 211],
           [ 97, 218],
           [102, 215],
           [104, 218]])
    >>> detector_extractor2.keypoints[matches[10:15, 1]]
    array([[297,  95],
           [301,  97],
           [294,  97],
           [297, 102],
           [293, 104]])

    c                 ó�  — |dv r|| _         nt        d«      ‚|| _        || _        ||z  | _        || _        dd|z  z  dz
  dz  |z  | _        || _        || _        |	| _	        |
| _
        || _        || _        || _        d|z  | _        d | _        d | _        d | _        d | _        d | _        d | _        d | _        d | _        d | _        y )N)r   r   é   zupsampling must be 1, 2 or 4r   r   g,Ê5æ‹¢Ð?)Ú
upsamplingÚ
ValueErrorÚ	n_octavesÚn_scalesÚ	sigma_minÚsigma_inÚc_dogÚc_edgeÚn_binsÚ
lambda_oriÚc_maxÚlambda_descrÚn_histÚn_oriÚ	delta_minÚfloat_dtypeÚscalespace_sigmasÚ	keypointsr   ÚsigmasÚscalesÚorientationsÚoctavesÚdescriptors)ÚselfrH   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   s                 r   Ú__init__zSIFT.__init__é   sà   € ð  ˜Ñ"Ø(ˆD�OäÐ;Ó<Ð<Ø"ˆŒØ ˆŒØ" ZÑ/ˆŒØ ˆŒØ˜A ™LÑ)¨AÑ-Ð2BÑCÀeÑKˆŒ
ØˆŒØˆŒØ$ˆŒØˆŒ
Ø(ˆÔØˆŒØˆŒ
Ø˜Z™ˆŒØˆÔØ!%ˆÔØˆŒØˆŒØˆŒØˆŒØ ˆÔØˆŒØˆÕr   c                 óž   — | j                   t        j                  dt        j                  | j                  «      | j
                  ¬«      z  }|S )z%The sampling distances of all octavesr   ©Údtype)rV   r5   ÚpowerÚarangerJ   rW   )r_   Údeltass     r   rf   zSIFT.deltas  s>   € ð —‘¤"§(¡(ØŒr�y‰y˜Ÿ™Ó(°×0@Ñ0@ô#
ñ 
ˆð ˆr   c                 ó®   — d}t        |«      | j                  z  }t        t        j                  ||z  «      dz   «      }|| j
                  k  r|| _        y y )Né   r   )ÚminrH   ÚintÚmathÚlog2rJ   )r_   Úimage_shapeÚsize_minÚs0Úmax_octavess        r   Ú_set_number_of_octaveszSIFT._set_number_of_octaves  sN   € ØˆÜ�Ó §¡Ñ/ˆÜœ$Ÿ)™) B¨¡MÓ2°QÑ6Ó7ˆØ˜Ÿ™Ò'Ø(ˆD�Nð (r   c           	      ó®  — g }| j                   dkD  rt        || j                   d¬«      }t        || j                   t        j                  | j
                  dz  | j                  dz  z
  «      z  d¬«      }t        j                  dt        j                  | j                  dz   «      | j                  z  «      }|| j
                  z  }| j                  dd…t        j                  f   | j                  d   z  |t        j                  dd…f   z  }|| _        t        j                  ||z  d¬	«      }t        j                  |«      | j                  dd…t        j                  f   z  }t        | j                   «      D ]Õ  }t        j"                  | j                  dz   f|j$                  z   | j&                  d
¬«      }||d<   t        d| j                  dz   «      D ]"  }	t        ||	dz
     |||	dz
  f   d||	   ¬«       Œ$ |j)                  t        j*                  |dd«      «       || j                   dz
  k  sŒ¼|| j                     ddd…ddd…f   }Œ× |S )z§Source: "Anatomy of the SIFT Method" Alg. 1
        Construction of the scalespace by gradually blurring (scales) and
        downscaling (octaves) the image.
        r   )Úorderr   Úreflect)ÚsigmaÚmodeé   Nr   r3   ÚC)rc   rs   )ru   rv   Úoutr2   )rH   r	   r   rk   ÚsqrtrL   rM   r5   rd   re   rK   rf   ÚnewaxisrX   ÚdiffÚrangerJ   ÚemptyÚshaperW   ÚappendÚmoveaxis)
r_   ÚimageÚ
scalespaceÚtmprZ   Úvar_diffÚgaussian_sigmasÚoÚoctaveÚss
             r   Ú_create_scalespacezSIFT._create_scalespace#  s  € ð
 ˆ
Ø�?‰?˜QÒÜ˜E 4§?¡?¸!Ô<ˆEô ØØ—/‘/¤D§I¡I¨d¯n©n¸aÑ.?À$Ç-Á-ÐQRÑBRÑ.RÓ$SÑSØô
ˆô �h‰h�qœ"Ÿ)™) D§M¡M°AÑ$5Ó6¸¿¹ÑFÓGˆØˆt�~‰~Ñˆà—‘šQ¤§
¡
˜]Ñ+¨d¯k©k¸!©nÑ<¸sÄ2Ç:Á:ÊqÀ=Ñ?QÑQˆØ!'ˆÔô —7‘7˜6 F™?°Ô3ˆÜŸ'™' (Ó+¨d¯k©kº!¼R¿Z¹Z¸-Ñ.HÑHˆô �t—~‘~Ö&ˆAô —X‘XØ—‘ Ñ"Ð$ u§{¡{Ñ2¸$×:JÑ:JÐRUôˆFð ˆF�1‰IÜ˜1˜dŸm™m¨aÑ/Ö0�äØ˜1˜q™5‘MØ)¨!¨Q°©U¨(Ñ3Ø"Ø˜q™	ö	ð 1ð ×ÑœbŸk™k¨&°!°RÓ8Ô9Ø�4—>‘> AÑ%Ó%à˜tŸ}™}Ñ-©c°¨c±3°Q°3¨hÑ7‘ð' 'ð( Ðr   c                 ó€   — |d d …df   dkD  |d d …df   |d   dz
  k  z  |d d …df   dkD  z  |d d …df   |d   dz
  k  z  S )Nr   r   r   )r_   ÚaÚdims      r   Ú_inrangezSIFT._inrange[  sf   € àŠq�!ˆt‰W�q‰[Ø’�A�‰w˜˜Q™ !™Ñ#ñ%à’�A�‰w˜‰{ñð ’�A�‰w˜˜Q™ !™Ñ#ñ%ð	
r   c                 óp	  — g }g }g }| j                   dz  }t        t        || j                  «      «      D �]Ã  \  }\  }}	t	        t        j                  |«      |«      }
|
j                  dk(  r%|j                  t        j                  d«      «       Œ]|j                  }d}d}t        |«      D ]ì  }|dkD  r|
| j                  |
|«      dd…f   }
t        ||
«      }t        ||
«      }t        ||«      }||dz
  k(  r n t        j                   ||kD  |
dz   t#        |D �cg c]  }|dz
  ‘Œ	 c}«      k  «      }t        j                   || k  |
dz
  dkD  «      }t        j$                  t        j&                  ||«      «      s n|
|xx   dz  cc<   |
|xx   dz  cc<   Œî t        j(                  t        j*                  «      |k  d¬«      }|
|   }
||   }D �cg c]  }||   ‘Œ	 }}||
dd…df   |
dd…df   |
dd…d	f   f   }|}t        d
«      D ]  }|d||   z  |dd…|f   z  z  }Œ d   |   |d   |   |d
   |   }}}| j,                  d   | j,                  d   z  }| j                   }t        j*                  |«      |kD  }t        j.                  | j0                  dz   «      | j0                  z  }t3        ||   ||   ||   «      } t        j*                  | «      |k  }!|
|   |!   }
||   |!   }|
dd…dd	…f   |dd…dd	…f   z   |	z  j5                  | j6                  «      }"| j,                  ||
dd…d	f   f   t        j8                  ||dd…d	f   «      z  }#t        j(                  t        j                   |"|#dd…t
        j:                  f   z
  dkD  |"|#dd…t
        j:                  f   z   |k  «      d¬«      }$|j                  |"|$   «       |j                  |
|$d	f   «       |j                  |#|$   «       �ŒÆ t        j<                  t        |«      D ��%cg c]$  \  }}%t        j>                  tA        |%«      |«      ‘Œ& c}%}«      }&tA        |&«      dk(  rtC        d«      ‚t        j<                  |«      }t        j<                  |«      }t        j<                  |«      }||||&fS c c}w c c}w c c}%}w )aL  Source: "Anatomy of the SIFT Method" Alg. 4-9
        1) first find all extrema of a (3, 3, 3) neighborhood
        2) use second order Taylor development to refine the positions to
           sub-pixel precision
        3) filter out extrema that have low contrast and lie on edges or close
           to the image borders
        çš™™™™™é?r   )r   r   é   g333333ã?Nr   r3   r   rw   r   )r   r   )r   r   g        zoSIFT found no features. Try passing in an image containing greater intensity contrasts between adjacent pixels.)"rN   Ú	enumerateÚziprf   r   r5   ÚascontiguousarrayÚsizer€   r~   r   r}   rŽ   r&   r0   rC   Úlogical_andÚtupleÚanyÚ
logical_orÚallÚabsrX   ÚsquarerO   r   ÚastyperW   rd   r{   ÚconcatenateÚfullÚlenÚRuntimeError)'r_   ÚdogspaceÚ	img_shapeÚextrema_posÚextrema_scalesÚextrema_sigmasÚ	thresholdr‡   rˆ   ÚdeltaÚkeysÚoshapeÚrefinement_iterationsÚ
offset_maxÚir7   r8   ÚoffrŒ   Úwrong_position_posÚwrong_position_negÚfinishedÚgÚvalsÚwr*   r+   r-   Ú
sigmaratioÚcontrast_thresholdÚcontrast_filterÚedge_thresholdÚedge_responseÚedge_filterÚyxrZ   Úborder_filterÚpÚoctave_indicess'                                          r   Ú_find_localize_evaluatezSIFT._find_localize_evaluatec  sÓ  € ð ˆØˆØˆØ—J‘J Ñ$ˆ	Ü"+¬C°¸$¿+¹+Ó,F×"GÑˆA‰�˜äœb×2Ñ2°6Ó:¸IÓFˆDØ�y‰y˜AŠ~Ø×"Ñ"¤2§8¡8¨FÓ#3Ô4Øð —\‘\ˆFØ$%Ð!ØˆJÜÐ0Ö1�Ø�q’5à §¡¨d°FÓ ;ºQÐ >Ñ?�Dô (¨°Ó5�Ü ¨Ó-�ô ˜t TÓ*�ØÐ-°Ñ1Ò1Ùô &(§^¡^Ø˜*Ñ$ d¨Q¡h´ÁvÓ7NÁvÀ!¸¸A»ÀvÑ7NÓ1OÑ&Oó&Ð"ô &(§^¡^°C¸:¸+Ñ4EÀtÈaÁxÐRSÁ|Ó%TÐ"Ü—v‘vœbŸm™mÐ,>Ð@RÓSÔTÙØÐ'Ó(¨AÑ-Ó(ØÐ'Ó(¨AÑ-Ô(ð- 2ô2 —v‘vœbŸf™f S›k¨JÑ6¸QÔ?ˆHØ˜‘>ˆDØ�h‘-ˆCÙ)-Ó.© A�A�h“K¨ˆDÐ.ð ˜$šq !˜t™* dª1¨a¨4¡j°$²q¸!°t±*Ð<Ñ=ˆDàˆAÜ˜1–X�Ø�S˜4 ™7‘] Sª¨A¨¡YÑ.Ñ.‘ð ð ! ™G HÑ-¨t°A©w°xÑ/@À$ÀqÁ'È(ÑBS�c�ˆCà×/Ñ/°Ñ5¸×8NÑ8NÈtÑ8TÑTˆJð "&§¡ÐÜ Ÿf™f Q›iÐ*<Ñ<ˆOäŸY™Y t§{¡{°Q¡Ó7¸$¿+¹+ÑEˆNÜ%Ø�OÑ$ c¨/Ñ&:¸CÀÑ<PóˆMô Ÿ&™& Ó/°>ÑAˆKà˜Ñ(¨Ñ5ˆDØ�oÑ& {Ñ3ˆCØš˜2˜A˜2˜‘; ¢Q¨¨¨ U¡Ñ+¨uÑ4×<Ñ<¸T×=MÑ=MÓNˆBà×+Ñ+¨A¨t²A°q°D©z¨MÑ:¼R¿X¹XØ˜C¢ 1 ™Ió>ñ ˆFô ŸF™FÜ—‘Ø˜&¢¤B§J¡J Ñ/Ñ/°3Ñ6Ø˜&¢¤B§J¡J Ñ/Ñ/°9Ñ<óð ôˆMð ×Ñ˜r -Ñ0Ô1Ø×!Ñ! $ }°aÐ'7Ñ"8Ô9Ø×!Ñ! &¨Ñ"7Ö8ð] #Hô` Ÿ™Ü,5°kÔ,BÔCÑ,B¡D A qŒR�W‰W”S˜“V˜QÕÐ,BÒCó
ˆô ˆ~Ó !Ò#ÜðGóð ô
 —n‘n [Ó1ˆÜŸ™¨Ó7ˆÜŸ™¨Ó7ˆØ˜N¨N¸NÐJÐJùòE 8Oùò /ùóT Ds   ÄR(ÇR-Ð)R2
c                 óH   — |d   |d   z
  d|d   |d   z   d|d   z  z
  z  z  S )z;Refine the position of the peak by fitting it to a parabolar   r   r   r   )r_   Úhs     r   Ú_fitz	SIFT._fitÎ  s7   € à�!‘�q˜‘t‘  Q q¡T¨A¨a©D¡[°1°q¸±t±8Ñ%;Ñ <Ñ=Ð=r   c                 ó  — g }g }g }g }	t        j                  || j                  ¬«      }
d}t        t	        || j
                  «      «      D �])  \  }\  }}|j                  t        j                  |«      «       ||k(  }t        j                  |«      sŒI||   }||   }||   }|j                  dd }||z  }||z  }d| j                  z  |z  }t        j                  d||dd…t         j                  f   z
  dz   «      j                  t        «      }t        j                  ||dd…t         j                  f   z   dz   |d   dz
  |d   dz
  f«      j                  t        «      }t        j                   | j"                  | j                  ¬«      }t        j$                  dd	| j                  ¬«      }t'        t)        |«      «      D �]¬  }d|dd t        j*                  t        j,                  ||df   ||df   dz   «      t        j,                  ||df   ||df   dz   «      d
d¬«      \  }}||   d   ||||   f   }||   d   ||||   f   }|j                  | j                  d¬«      }|j                  | j                  d¬«      }|||df   z  }|||df   z  }t        j.                  t        j0                  |«      t        j0                  |«      z   «      } t        j2                  t        j4                  ||«      dt         j6                  z  «      }!t        j8                  t        j:                  ||z  ||z  z   d| j                  ||   z  dz  z  «      «      }"t        j<                  |!dt         j6                  z  z  | j"                  z  dz   | j"                  z  «      j                  t        «      }#t         j>                  jA                  ||#|"| z  «       t        jB                  |dd ||dd f«      }t'        d«      D ]  }$t        jD                  ||d¬«      }Œ |dd }tG        jH                  |dgd¬«      }%t        jJ                  t        jL                  || jN                  t        jP                  |«      z  k\  |%|k(  «      «      }&t        |&d   «      D ]Ï  \  }}'t        j,                  |'dz
  |'dz   «      t)        |«      z  }(|'| jS                  ||(   «      z   dz   dz  t         j6                  z  | j"                  z  })|)t         j6                  kD  r|)dt         j6                  z  z  })|dk(  r|)|
|<   Œ�|j                  |«       |j                  |)«       |	j                  |«       ŒÑ |dz  }�Œ¯ �Œ, t        jB                  |||   f«      | _*        t        jB                  |||   f«      | _+        t        jB                  |||   f«      | _,        t        jB                  |
|f«      | _-        t        jB                  ||	f«      | _.        |S )z~Source: "Anatomy of the SIFT Method" Alg. 11
        Calculates the orientation of the gradient around every keypoint
        rb   r   Nr   rw   r   r   )rw   gUUUUUUÕ?ÚijT©ÚindexingÚsparseF©Úcopyéþÿÿÿiúÿÿÿé   Úsame)rv   Úwrap)/r5   Ú
zeros_likerW   r’   r“   rf   r€   Úgradientr˜   r   rQ   Úmaximumr{   r�   rj   Úminimumr~   rP   rŸ   r}   r    Úmeshgridre   rz   rœ   ÚmodÚarctan2ÚpiÚexpÚdivideÚfloorÚaddÚatrž   ÚconvolveÚndiÚmaximum_filterÚnonzeror–   rR   ÚmaxrÂ   r   r[   rZ   r\   r]   )*r_   Úpositions_octÚ
scales_octÚ
sigmas_octr]   Úgaussian_scalespaceÚgradient_spaceÚkeypoint_indicesÚkeypoint_anglesÚkeypoint_octaver\   Ú	key_countr‡   rˆ   r¨   Úin_octr   r[   rZ   rª   r»   ru   ÚradiusÚp_minÚp_maxÚhistÚ
avg_kernelÚkÚrÚcÚgradient_rowÚgradient_colÚ	magnitudeÚthetaÚkernelÚbinsÚ_Ú
max_filterÚmaximaÚmÚneighÚoris*                                             r   Ú_compute_orientationzSIFT._compute_orientationÒ  s~  € ð ˆàÐØˆØˆÜ—}‘} Z°t×7GÑ7GÔHˆØˆ	Ü"+¬CÐ0CÀTÇ[Á[Ó,Q×"RÑˆA‰�˜Ø×!Ñ!¤"§+¡+¨fÓ"5Ô6à ‘\ˆFÜ—6‘6˜&”>ØØ% fÑ-ˆIØ Ñ'ˆFØ Ñ'ˆFà—\‘\ " 1Ð%ˆFà˜UÑ"ˆBØ˜U‘NˆEð ˜Ÿ™Ñ(¨5Ñ0ˆFÜ—J‘J˜q " vªa´·±¨mÑ'<Ñ"<¸sÑ"BÓC×JÑJÌ3ÓOˆEÜ—J‘JØ�VšAœrŸz™z˜MÑ*Ñ*¨SÑ0°6¸!±9¸q±=À&ÈÁ)ÈaÁ-Ð2Póç‰f”S‹kð ô —8‘8˜DŸK™K¨t×/?Ñ/?Ô@ˆDÜŸ™  u°D×4DÑ4DÔEˆJÜœ3˜r›7—^�Ø�‘Q�ô —{‘{Ü—I‘I˜e A q D™k¨5°°A°©;¸©?Ó;Ü—I‘I˜e A q D™k¨5°°A°©;¸©?Ó;Ø!Øô	‘��1ð  .¨aÑ0°Ñ3°A°q¸&À¹)°OÑD�Ø-¨aÑ0°Ñ3°A°q¸&À¹)°OÑD�Ø—H‘H˜T×-Ñ-°E�HÓ:�Ø—H‘H˜T×-Ñ-°E�HÓ:�Ø�R˜˜1˜‘X‘�Ø�R˜˜1˜‘X‘�ô ŸG™G¤B§I¡I¨lÓ$;¼b¿i¹iÈÓ>UÑ$UÓV�	ÜŸ™œrŸz™z¨,¸ÓEÀqÌ2Ï5É5ÁyÓQ�ô Ÿ™Ü—I‘I˜a !™e a¨!¡e™m¨R°4·?±?ÀUÈ1ÁXÑ3MÐRSÑ2SÑ-SÓTó�ô
 —x‘xØ˜a¤"§%¡%™iÑ(¨4¯;©;Ñ6¸Ñ<ÀÇÁÑKóç‘&œ“+ð ô —‘—	‘	˜$  f¨yÑ&8Ô9ô —~‘~ t¨B¨C y°$¸¸R¸a¸Ð&AÓB�Ü˜qž�AÜŸ;™; t¨Z¸fÔE‘Dð "à˜A˜b�z�Ü ×/Ñ/°°q°cÀÔG�
ô Ÿ™Ü—N‘NØ §¡¬b¯f©f°T«lÑ!:Ñ;¸ZÈ4Ñ=Oóó�ô & f¨Q¡iÖ0‘D�A�qÜŸI™I a¨!¡e¨Q°©UÓ3´c¸$³iÑ?�Eð ˜tŸy™y¨¨e©Ó5Ñ5¸Ñ;¸qÑ@Ä2Ç5Á5ÑHÈ4Ï;É;ÑV�CØœRŸU™U’{Ø˜q¤2§5¡5™yÑ(˜Ø˜A’vØ25˜ YÒ/à(×/Ñ/°	Ô:Ø'×.Ñ.¨sÔ3Ø'×.Ñ.¨qÕ1ð 1ð ˜Q‘’	ò} $ð1 #Sôn Ÿ™Ø˜MÐ*:Ñ;Ð<ó
ˆŒô —n‘n j°*Ð=MÑ2NÐ%OÓPˆŒÜ—n‘n j°*Ð=MÑ2NÐ%OÓPˆŒÜŸN™N¨L¸/Ð+JÓKˆÔÜ—~‘~ w°Ð&@ÓAˆŒàÐr   c                 óŒ   — t        j                  |«      }t        j                  |«      }||z  ||z  z   }| |z  ||z  z   }||fS )N)rk   ÚcosÚsin)r_   ÚrowÚcolÚanglerñ   r‰   Úrot_rowÚrot_cols           r   Ú_rotatezSIFT._rotate@  sM   € Ü�H‰H�U‹OˆÜ�H‰H�U‹OˆØ�c‘'˜A ™GÑ#ˆØ�"�s‘(˜Q ™WÑ$ˆØ˜ÐÐr   c                 ó,  — t        | j                  «      }t        j                  || j                  dz  | j
                  z  ft        j                  ¬«      | _        t        j                  d| j                  dz   | j                  ¬«      }t        j                  d| j
                  dz   | j                  ¬«      }t        j                  |«      }t        t        || j                  «      «      D �]#  \  }\  }}| j                  |k(  }	t        j                  |	«      sŒ/| j                  |	   }
| j                  |	   }| j                   |	   }| j"                  |	   }||	   }|d   j$                  dd }|
|z  }||z  }| j&                  dd| j                  z  z   z  |z  }t)        j*                  d«      |z  }t        j,                  t        j.                  d||dd…t        j0                  f   z
  dz   «      t2        ¬«      }t        j,                  t        j4                  ||dd…t        j0                  f   z   dz   |d   dz
  |d   dz
  f«      t2        ¬«      }t7        t        |«      «      D �]¤  }t9        ||   «      }t9        ||   «      }t        j:                  | j                  | j                  | j
                  f| j                  ¬«      }t        j<                  t        j                  ||df   ||df   «      t        j                  ||df   ||df   «      dd¬	«      \  }}t        j>                  |||df   | j                  ¬«      }t        j>                  |||df   | j                  ¬«      }| jA                  |||«      \  }}t        j.                  t        jB                  |«      t        jB                  |«      «      |k  }||   ||   }}t        jD                  |«      \  }} ||df   }|d| f   }|d   ||||   f   }!|d   ||||   f   }"t        jF                  |"|!«      |z
  }#| j&                  t9        ||   «      z  }$t        jH                  ||z  ||z  z   d
|$dz  z  z  «      }%t        j*                  |!|!z  |"|"z  z   «      |%z  }&d|$z  | j                  z  }'|d| j                  z   dz  z
  |'z  }(|'})dt        jJ                  z  |z  | j
                  z  }*t        jB                  t        j>                  jM                  |(|«      «      }+t        jB                  t        j>                  jM                  |(|«      «      },tO        |*|#«      \  }-}.tQ        ||-|.|&|+|,|)«       |jS                  d«      }t        j4                  |dt        jT                  jW                  |«      z  «      }d|z  t        jT                  jW                  |«      z  }/t        j4                  t        jX                  |/«      d«      }/|/| j                  ||   dd…f<   �Œ§ �Œ& y)zjSource: "Anatomy of the SIFT Method" Alg. 12
        Calculates the descriptor for every keypoint
        r   rb   r   r   Nr   rÄ   TrÅ   rÊ   r2   gš™™™™™É?i   éÿ   )-r    r[   r5   r~   rT   rU   Úuint8r^   re   rW   r’   r“   rf   r]   r˜   r   rZ   r\   r   rS   rk   rz   ÚasarrayrÐ   r{   rj   rÑ   r}   ÚfloatÚzerosrÒ   Úsubtractr  r›   rÞ   rÔ   rÖ   rÕ   Úouterr   r   ÚreshapeÚlinalgÚnormrØ   )0r_   rä   Ún_keyÚhistsr÷   Úkey_numbersr‡   rÏ   r¨   ré   r   r[   rZ   r\   Únumbersr�   Ú
center_posru   rê   Úradius_patchrë   rì   rï   Úrad_krý   Ú
histogramsrð   rñ   Úr_normÚc_normÚinsideÚr_idxÚc_idxrò   ró   rõ   Úlam_sigrö   rô   Úlam_sig_ratioÚrc_binsÚrc_bin_spacingÚori_binsÚdist_rÚdist_cÚnear_tÚ
near_t_valÚ
descriptors0                                                   r   Ú_compute_descriptorzSIFT._compute_descriptorG  sb  € ô �D—K‘KÓ ˆÜŸ8™8Ø�D—K‘K ‘N T§Z¡ZÑ/Ð0¼¿¹ô
ˆÔô
 —	‘	˜!˜TŸ[™[¨1™_°D×4DÑ4DÔEˆä�y‰y˜˜DŸJ™J¨™N°$×2BÑ2BÔCˆä—i‘i Ó&ˆÜ$-¬c°.À$Ç+Á+Ó.N×$OÑ ˆAÑ �˜%Ø—\‘\ QÑ&ˆFÜ—6‘6˜&”>ØØŸ™ vÑ.ˆIØ—[‘[ Ñ(ˆFØ—[‘[ Ñ(ˆFØ×,Ñ,¨VÑ4ˆLØ! &Ñ)ˆGà˜1‘+×#Ñ# B QÐ'ˆCØ" UÑ*ˆJØ˜U‘NˆEð ×&Ñ&¨!¨a°$·+±+©oÑ*=Ñ>ÀÑFˆFÜŸ9™9 Q›<¨&Ñ0ˆLÜ—J‘JÜ—
‘
˜1˜j¨<º¼2¿:¹:¸Ñ+FÑFÈÑLÓMÔUXôˆEô —J‘JÜ—
‘
Ø ªa´·±¨mÑ!<Ñ<¸sÑBØ˜‘V˜a‘Z  Q¡¨!¡Ð,óô ôˆEô œ3˜u›:×&�Ü˜f Q™iÓ(�Ü˜L¨™OÓ,�ÜŸX™XØ—[‘[ $§+¡+¨t¯z©zÐ:À$×BRÑBRô�
ô —{‘{Ü—I‘I˜e A q D™k¨5°°A°©;Ó7Ü—I‘I˜e A q D™k¨5°°A°©;Ó7Ø!Øô	‘��1ô Ÿ™ Q¨
°1°a°4Ñ(8À×@PÑ@PÔQ�ÜŸ™ Q¨
°1°a°4Ñ(8À×@PÑ@PÔQ�Ø!%§¡¨f°f¸cÓ!B‘�˜ô Ÿ™¤B§F¡F¨6£N´B·F±F¸6³NÓCÀeÑK�Ø!'¨¡°¸±˜�Ü!Ÿz™z¨&Ó1‘��uØ�e˜Q�h‘K�Ø�a˜�h‘K�Ø'¨™{¨1¨a°¸±¨?Ñ;�Ø'¨™{¨1¨a°¸±¨?Ñ;�äŸ
™
 <°Ó>ÀÑD�Ø×+Ñ+¬e°E¸!±H«oÑ=�äŸ™ ¨&¡°6¸F±?Ñ!BÀrÈGÐUVÉJÁÑ WÓX�ä—G‘G˜L¨<Ñ7¸,ÈÑ:UÑUÓVØñð ð
 !" G¡¨d¯k©kÑ 9�Ø  A¨¯©¡O°qÑ#8Ñ8¸MÑI�Ø!.�Ø¤§¡™I¨Ñ,°·
±
Ñ:�ô Ÿ™¤§¡× 1Ñ 1°'¸6Ó BÓC�ÜŸ™¤§¡× 1Ñ 1°'¸6Ó BÓC�ô &4°H¸eÓ%DÑ"�˜
ô "ØØØØØØØ"ôð (×/Ñ/°Ó3�
äŸZ™Z¨
°C¼"¿)¹)¿.¹.ÈÓ:TÑ4TÓU�
à! JÑ.´"·)±)·.±.ÀÓ2LÑL�
äŸZ™Z¬¯©°Ó(<¸cÓB�
Ø2<�× Ñ  ¨¡ªQ Ó/òG 'ñ9 %Pr   c                 óØ   — t        |d«       t        |«      }t        |j                  «      | _        |j                  | j                  d¬«      }| j                  |j                  «       |S )Nr   FrÈ   )r   r
   r   rc   rW   r�   rq   r   )r_   r‚   s     r   Ú_preprocesszSIFT._preprocess·  sV   € Ü�˜ÔÜ˜UÓ#ˆÜ0°·±Ó=ˆÔØ—‘˜T×-Ñ-°E�Ó:ˆà×#Ñ# E§K¡KÔ0Øˆr   c                 ój  — | j                  |«      }| j                  |«      }|D �cg c]  }t        j                  |d¬«      ‘Œ }}| j	                  ||j
                  «      \  }}}}| j                  |||||«       | j                  j                  «       j                  t        «      | _        yc c}w )zxDetect the keypoints.

        Parameters
        ----------
        image : 2D array
            Input image.

        r   r3   N)r,  rŠ   r5   r|   r¿   r   rþ   r   Úroundr�   rj   rY   )	r_   r‚   rã   ÚlayerÚdog_scalespacer   r[   rZ   r]   s	            r   ÚdetectzSIFT.detectÀ  s«   € ð × Ñ  Ó'ˆà"×5Ñ5°eÓ<Ðá>QÓRÑ>Q°Uœ"Ÿ'™' %¨aÖ0Ð>QˆÐRà-1×-IÑ-IØ˜EŸK™Kó.
Ñ*ˆ	�6˜6 7ð 	×!Ñ!Ø�v˜v wÐ0Cô	
ð Ÿ™×-Ñ-Ó/×6Ñ6´sÓ;ˆ�ùò Ss   §B0c                 ó¸   — | j                  |«      }| j                  |«      }|D �cg c]  }t        j                  |«      ‘Œ }}| j	                  |«       yc c}w )zšExtract the descriptors for all keypoints in the image.

        Parameters
        ----------
        image : 2D array
            Input image.

        N)r,  rŠ   r5   rÏ   r*  )r_   r‚   rã   rˆ   rä   s        r   ÚextractzSIFT.extractÙ  sX   € ð × Ñ  Ó'ˆà"×5Ñ5°eÓ<Ðá<OÓPÑ<O°&œ"Ÿ+™+ fÕ-Ð<OˆÐPà× Ñ  Õ0ùò Qs   §Ac                 óŒ  — | j                  |«      }| j                  |«      }|D �cg c]  }t        j                  |d¬«      ‘Œ }}| j	                  ||j
                  «      \  }}}}| j                  |||||«      }	| j                  |	«       | j                  j                  «       j                  t        «      | _        yc c}w )z–Detect the keypoints and extract their descriptors.

        Parameters
        ----------
        image : 2D array
            Input image.

        r   r3   N)r,  rŠ   r5   r|   r¿   r   rþ   r*  r   r.  r�   rj   rY   )
r_   r‚   rã   r/  r0  r   r[   rZ   r]   rä   s
             r   Údetect_and_extractzSIFT.detect_and_extractê  s»   € ð × Ñ  Ó'ˆà"×5Ñ5°eÓ<Ðá>QÓRÑ>Q°Uœ"Ÿ'™' %¨aÖ0Ð>QˆÐRà-1×-IÑ-IØ˜EŸK™Kó.
Ñ*ˆ	�6˜6 7ð ×2Ñ2Ø�v˜v wÐ0Có
ˆð 	× Ñ  Ô0àŸ™×-Ñ-Ó/×6Ñ6´sÓ;ˆ�ùò Ss   §CN)r   é   rw   gš™™™™™ù?r   gOè´�N‹?é
   é$   g      ø?r�   rË   rG   r6  )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r`   Úpropertyrf   rq   rŠ   rŽ   r¿   rÂ   rþ   r  r*  r,  r1  r3  r5  r   r   r   rE   rE   f   s�   „ ñ@ðH ØØØØØØØØØØØØó) ðV ñó ðò)ò6òp
òiKòV>òlò\ òn=ò`ò<ò21ó"<r   rE   )rk   Únumpyr5   Úscipy.ndimageÚndimagerÜ   Ú_shared.utilsr   r   Úfeature.utilr   r   Ú_shared.filtersr   Ú	transformr	   Úutilr
   Ú_siftr   r   r   r   r&   r0   rC   rE   r   r   r   Ú<module>rG     sI   ðÛ ã Ý ç ;ß ?Ý &Ý Ý ß @Ñ @ò)òò&*òD:ô8]
<ˆ?Ð/õ ]
<r   