
    1-Phr                         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dS )    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        T/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/skimage/feature/sift.py	_edgenessr      s,    #IE)cCi'KEM[((    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 )zGradient 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!VR^	s262r>2	2B#IB	Ra^	s2rAvr>2	2B#IB	RR!V^	s2r26>2	2B#IBr2:r   c                    |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 )zCompute 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2r2:F
BFBN
aQB/
/&
8C
BQN
aBFB/
/&
8C
BBFN
aBQ/
/&
8C
	"q&"q&"

BFBFB
	 
BFBFB
	  BFBFB
	 C 	"q&"b1f

BFBQ
	 
BFBQ
	  BFBQ
	 C 	"b1fb1f

BQQ
	 
BQQ
	  BQQ
	 C c3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   sx    $( Cc3SJBB
)c/C39s?C39s?C1s7S=3C39s?C
)cCi
3	&B
)cCi
3	&B
)cCi
3	&B
)cCi
3	&B
)cCi
3	&B
)cCi
3	&BcBhb 27*GcBhb 27*GcBhb 27*G8Wgw/b99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dS )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]])

    r         皙?r   O贁N?
   $         ?皙?      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 | _        d S )N)r   r   rO   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)selfrQ   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   s                 r   __init__zSIFT.__init__   s      ""(DOO;<<<" "Z/ AL)A-2BCeK
$
(
Z!% r   c                 |    | j         t          j        dt          j        | j                  | j                  z  }|S )z%The sampling distances of all octavesr   dtype)r_   r5   powerarangerS   r`   )rh   deltass     r   ro   zSIFT.deltas  s@     "(ry((0@#
 #
 #
 
 r   c                     d}t          |          | j        z  }t          t          j        ||z            dz             }|| j        k     r	|| _        d S d S )N   r   )minrQ   intmathlog2rS   )rh   image_shapesize_mins0max_octavess        r   _set_number_of_octaveszSIFT._set_number_of_octaves  s[    /$)BM22Q677''(DNNN ('r   c           	      4   g }| j         dk    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||	                    0|                    t          j        |dd                     || j        dz
  k     r|| j
                 ddddddf         }|S )zSource: "Anatomy of the SIFT Method" Alg. 1
        Construction of the scalespace by gradually blurring (scales) and
        downscaling (octaves) the image.
        r   )orderr   reflect)sigmamoderG   Nr   r3   C)rl   r|   )r~   r   outr2   )rQ   r	   r   rt   sqrtrU   rV   r5   rm   rn   rT   ro   newaxisra   diffrangerS   emptyshaper`   appendmoveaxis)
rh   image
scalespacetmprc   var_diffgaussian_sigmasooctavess
             r   _create_scalespacezSIFT._create_scalespace#  s<   
 
?QE4?!<<<E /DIdna.?$-QRBR.R$S$SS
 
 
 hq")DMA$566FGGt~QQQ
]+dk!n<s2:qqq=?QQ!' 76F?333'(++dk!!!RZ-.HH t~&& 	8 	8A X"$u{2$:JRU  F F1I1dma/00  1q5M)!QU(3"q		     bk&!R889994>A%%%t}-ccc33Q3h7r   c                     |d d df         dk    |d d df         |d         dz
  k     z  |d d df         dk    z  |d d df         |d         dz
  k     z  S )Nr   r   r   )rh   adims      r   _inrangezSIFT._inrange[  sv    qqq!tWq[AwQ!#%Aw{ AwQ!#%	
r   c           
      	  # g }g }g }| j         dz  }t          t          || j                            D ]#\  }\  }}	t	          t          j        |          |          }
|
j        dk    r(|                    t          j	        d                     ^|j
        }d}d}t          |          D ]}|dk    r |
|                     |
|          ddf         }
t          ||
          }t          ||
          }t          ||          }||dz
  k    r nt          j        ||k    |
dz   t#          d |D                       k               }t          j        || k     |
dz
  dk              }t          j        t          j        ||                    s n"|
|xx         dz  cc<   |
|xx         dz  cc<   t          j        t          j        |          |k     d	          #|
#         }
|#         }#fd
|D             }||
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        |          |k    }t          j        | j        dz             | j        z  }t3          ||         ||         ||                   }t          j        |          |k    }|
|         |         }
||         |         }|
ddddf         |ddddf         z   |	z                      | j                  }| j        ||
dddf         f         t          j        ||dddf                   z  } t          j        t          j        || ddt
          j        f         z
  dk    || ddt
          j        f         z   |k               d	          }!|                    ||!                    |                    |
|!df                    |                    | |!                    %t          j        d t          |          D                       }"t?          |"          dk    rtA          d          t          j        |          }t          j        |          }t          j        |          }||||"fS )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
        rM   r   )r   r      g333333?Nr   c                     g | ]}|d z
  S )r   r   ).0r   s     r   
<listcomp>z0SIFT._find_localize_evaluate.<locals>.<listcomp>  s    7N7N7N!A7N7N7Nr   r3   c                      g | ]
}|         S r   r   )r   gfinisheds     r   r   z0SIFT._find_localize_evaluate.<locals>.<listcomp>  s    ...AAhK...r   r   rG   r   )r   r   )r   r   g        c                 X    g | ]'\  }}t          j        t          |          |          (S r   )r5   fulllen)r   ips      r   r   z0SIFT._find_localize_evaluate.<locals>.<listcomp>  s.    CCCDAqRWSVVQCCCr   zoSIFT found no features. Try passing in an image containing greater intensity contrasts between adjacent pixels.)!rW   	enumeratezipro   r   r5   ascontiguousarraysizer   r   r   r   r   r&   r0   rC   logical_andtupleany
logical_orallabsra   squarerX   r   astyper`   rm   r   concatenater   RuntimeError)$rh   dogspace	img_shapeextrema_posextrema_scalesextrema_sigmas	thresholdr   r   deltakeysoshaperefinement_iterations
offset_maxr   r7   r8   offwrong_position_poswrong_position_negvalswr*   r+   r-   
sigmaratiocontrast_thresholdcontrast_filteredge_thresholdedge_responseedge_filteryxrc   border_filteroctave_indicesr   s$                                      @r   _find_localize_evaluatezSIFT._find_localize_evaluatec  s\    J$	"+C$+,F,F"G"G N	9 N	9Ab26::IFFDyA~~""28F#3#3444 \F$%!J011 . .q55dF ; ;QQQ >?D (55-- tT**-111E &(^*$dQh7N7Nv7N7N7N1O1O&O& &" &(^C:+4EtaxRS|%T%T"vbm,>@RSSTT E'(((A-((('(((A-(((( vbfSkkJ6Q???H>Dh-C.......D $qqq!t*d111a4j$qqq!t*<=DA1XX / /S47]SAY.. GH-tAwx/@$q'(BScC/58Nt8TTJ "& fQii*<<OYt{Q77$+EN%O$c/&:C<P M &//>AK(5Do&{3C2A2;QQQU+u4<<T=MNNB+AtAAAqDzM:RXC1I> > F F&BJ//36&BJ//9<    M r-0111!!$}a'7"8999!!&"78888CCIk,B,BCCC
 
 ~!##G  
 n[117777NNNJJr   c                 f    |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   )rh   hs     r   _fitz	SIFT._fit  s7    !qtQqTAaD[1qt8%; <==r   c                 t   g }g }g }g }	t          j        || j                  }
d}t          t	          || j                            D ]U\  }\  }}|                    t          j        |                     ||k    }t          j        |          sK||         }||         }||         }|j	        dd         }||z  }||z  }d| j
        z  |z  }t          j        d||ddt           j        f         z
  dz                                 t                    }t          j        ||ddt           j        f         z   dz   |d         dz
  |d         dz
  f                              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        d          }|                    | j        d          }|||df         z  }|||df         z  }t          j        t          j        |          t          j        |          z             } t          j        t          j        ||          dt           j        z            }!t          j        t          j        ||z  ||z  z   d| j
        ||         z  dz  z                      }"t          j        |!dt           j        z  z  | j        z  dz   | j        z                                t                    }#t           j                             ||#|"| z             t          j!        |dd         ||dd         f          }t'          d          D ]}$t          j"        ||d          }|dd         }tG          j$        |dgd          }%t          j%        t          j&        || j'        t          j(        |          z  k    |%|k                        }&t          |&d                   D ]\  }}'t          j        |'dz
  |'dz             t)          |          z  }(|'| )                    ||(                   z   dz   dz  t           j        z  | j        z  })|)t           j        k    r|)dt           j        z  z  })|dk    r|)|
|<   |                    |           |                    |)           |	                    |           |dz  }ҐWt          j!        |||         f          | _*        t          j!        |||         f          | _+        t          j!        |||         f          | _,        t          j!        |
|f          | _-        t          j!        ||	f          | _.        |S )z~Source: "Anatomy of the SIFT Method" Alg. 11
        Calculates the orientation of the gradient around every keypoint
        rk   r   Nr   rG   r   r   )rG   gUUUUUU?ijTindexingsparseFcopyirN   same)r   wrap)/r5   
zeros_liker`   r   r   ro   r   gradientr   r   rZ   maximumr   r   rs   minimumr   rY   r   r   r   meshgridrn   r   r   modarctan2piexpdivideflooraddatr   convolvendimaximum_filternonzeror   r[   maxr   r   rd   rc   re   rf   )*rh   positions_oct
scales_oct
sigmas_octrf   gaussian_scalespacegradient_spacekeypoint_indiceskeypoint_angleskeypoint_octavere   	key_countr   r   r   in_octr   rd   rc   r   r   r~   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
    }Zt7GHHH	"+C0CT[,Q,Q"R"R V	 V	A!!"+f"5"5666\F6&>> %f-I'F'F\"1"%FU"BUNE (50FJq"vaaam'<"<s"BCCJJ3OOEJVAAArzM**S06!9q=&)a-2P fSkk  8DKt/?@@@DuD4DEEEJ3r77^^ > >QQQ {IeAqDk5A;?;;IeAqDk5A;?;;!	  1  .a03Aq&)OD-a03Aq&)ODHHT-EH::HHT-EH::R1XR1X GBIl$;$;bi>U>U$UVV	rz,EEq25yQQ Ia!ea!emR4?U1X3MRS2S-STT 
 xa"%i(4;6<K &++  		$fy&8999 ~tBCCy$RaR&ABBq F FA;tZfEEEDDAbDz /qcGGG
 NbfTll!:;Z4=O   &fQi00 2 2DAqIa!eQU33c$ii?E tyye555;q@25H4;VCRU{{q25y(Avv25Y//(//	:::'..s333'..q1111Q		}>~ M*:;<
 
 nj*=M2N%OPPnj*=M2N%OPPNL/+JKK~w&@AAr   c                     t          j        |          }t          j        |          }||z  ||z  z   }| |z  ||z  z   }||fS )N)rt   cossin)rh   rowcolangler   r   rot_rowrot_cols           r   _rotatezSIFT._rotate@  sM    HUOOHUOO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          j        f         z
  dz             t2                    }t          j        t          j        ||ddt          j        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	                  }|                      |||          \  }}t          j        t          j!        |          t          j!        |                    |k     }||         ||         }}t          j"        |          \  }} ||df         }|d| f         }|d         ||||         f         }!|d         ||||         f         }"t          j#        |"|!          |z
  }#| j        t9          ||                   z  }$t          j$        ||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          j%        z  |z  | j        z  }*t          j!        t          j        &                    |(|                    }+t          j!        t          j        &                    |(|                    },tO          |*|#          \  }-}.tQ          ||-|.|&|+|,|)           |)                    d          }t          j        |dt          j*        +                    |          z            }d|z  t          j*        +                    |          z  }/t          j        t          j,        |/          d          }/|/| j        ||         ddf<   'dS )zjSource: "Anatomy of the SIFT Method" Alg. 12
        Calculates the descriptor for every keypoint
        r   rk   r   r   Nr   r   Tr   r   r2   g?i      )-r   rd   r5   r   r]   r^   uint8rg   rn   r`   r   r   ro   rf   r   r   rc   re   r   r\   rt   r   asarrayr   r   rs   r   r   floatzerosr   subtractr  r   r   r   r   r   outerr   r   reshapelinalgnormr   )0rh   r   n_keyhistsr  key_numbersr   r   r   r   r   rd   rc   re   numbersr   
center_posr~   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  s    DK  8DKNTZ/0
 
 

 	!T[1_D4DEEEyDJN$2BCCCi&&$-c.$+.N.N$O$O _	= _	= A %\Q&F6&>> v.I[(F[(F,V4L!&)G1+#BQB'C"U*JUNE &!a$+o*=>FF9Q<<&0LJ
1j<2:+FFLMMUX  E J
aaam!<<sBVaZQ!,    E 3u::&& C= C=fQi((LO,,X[$+tz:$BR  
 {IeAqDk5A;77IeAqDk5A;77!	  1 Q
1a4(8@PQQQQ
1a4(8@PQQQ!%ffc!B!B BF6NNBF6NNCCeK!'!z&11ueQhKahK'{1a?;'{1a?;
<>>D+eE!Hoo=&6F?!BrGUVJ WXXGL<7,:UUVV 
 !"Gdk 9 AOq#88MI!.I,
:  1 1'6 B BCC 1 1'6 B BCC &4He%D%D"
 ""   (//33
Z
C")..:T:T4TUU
!J.")..2L2LL
Z(<(<cBB
2< QQQ//GC=9_	= _	=r   c                     t          |d           t          |          }t          |j                  | _        |                    | j        d          }|                     |j                   |S )Nr   Fr   )r   r
   r   rl   r`   r   rz   r   )rh   r   s     r   _preprocesszSIFT._preprocess  sd    U##0==T-E::##EK000r   c                 P   |                      |          }|                     |          }d |D             }|                     ||j                  \  }}}}|                     |||||           | j                                                            t                    | _	        dS )zxDetect the keypoints.

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

        c                 :    g | ]}t          j        |d           S r   r3   r5   r   r   layers     r   r   zSIFT.detect.<locals>.<listcomp>  '    RRRU"'%a000RRRr   N)
r7  r   r   r   r	  r   roundr   rs   rb   )rh   r   r   dog_scalespacer   rd   rc   rf   s           r   detectzSIFT.detect  s       ''"55e<<RR>QRRR-1-I-IEK.
 .
*	667 	!!vvw0C	
 	
 	
 --//66s;;r   c                     |                      |          }|                     |          }d |D             }|                     |           dS )zExtract the descriptors for all keypoints in the image.

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

        c                 6    g | ]}t          j        |          S r   )r5   r   )r   r   s     r   r   z SIFT.extract.<locals>.<listcomp>  s"    PPP&"+f--PPPr   N)r7  r   r5  )rh   r   r   r   s       r   extractzSIFT.extract  sY       ''"55e<<PP<OPPP  00000r   c                 z   |                      |          }|                     |          }d |D             }|                     ||j                  \  }}}}|                     |||||          }|                     |           | j                                                            t                    | _
        dS )zDetect the keypoints and extract their descriptors.

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

        c                 :    g | ]}t          j        |d           S r:  r;  r<  s     r   r   z+SIFT.detect_and_extract.<locals>.<listcomp>  r>  r   N)r7  r   r   r   r	  r5  r   r?  r   rs   rb   )	rh   r   r   r@  r   rd   rc   rf   r   s	            r   detect_and_extractzSIFT.detect_and_extract  s       ''"55e<<RR>QRRR-1-I-IEK.
 .
*	667 22vvw0C
 
 	  000--//66s;;r   N)r   rF   rG   rH   r   rI   rJ   rK   rL   rM   rN   rO   rF   )__name__
__module____qualname____doc__ri   propertyro   rz   r   r   r   r   r	  r  r5  r7  rA  rD  rG  r   r   r   rE   rE   f   s>       @ @H )  )  )  ) V   X) ) )6 6 6p
 
 
iK iK iKV> > >l l l\     n= n= n=`  < < <21 1 1"< < < < <r   rE   )rt   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>rV     s.              ; ; ; ; ; ; ; ; ? ? ? ? ? ? ? ? & & & & & &             @ @ @ @ @ @ @ @ @ @) ) )  &* * *D: : :8]
< ]
< ]
< ]
< ]
<?/ ]
< ]
< ]
< ]
< ]
<r   