
    cCi a                        S SK r S SKJrJr  S SKrS SKrSSKJrJ	r	J
r
  SSKJrJr  SSKJrJrJrJrJrJrJrJrJrJrJrJrJr  SSKJrJrJrJ r   SSK!J"r"  S	S
K#J$r$  \" 5       (       a  S SK%J&r&J'r'  \" 5       (       a  S SK%r%\RP                  " \)5      r* SS\RV                  S\\\,\4      4S jjr- SS\S\\\,\4      S\4S jjr.S\4S jr/\"" SS9 " S S\5      5       r0S/r1g)    N)OptionalUnion   )BaseImageProcessorBatchFeatureget_size_dict)resizeto_channel_dimension_format)ChannelDimension
ImageInput	ImageTypePILImageResamplingget_image_typeinfer_channel_dimension_formatis_pil_imageis_scaled_imageis_valid_imageis_vision_availableto_numpy_arrayvalid_imagesvalidate_preprocess_arguments)
TensorTypeis_matplotlib_availableloggingrequires_backends)requires   )LightGlueKeypointMatchingOutput)Image	ImageDrawimageinput_data_formatc                    U[         R                  :X  aY  U R                  S   S:X  a  g[        R                  " U S   U S   :H  5      =(       a    [        R                  " U S   U S   :H  5      $ U[         R
                  :X  aY  U R                  S   S:X  a  g[        R                  " U S   U S	   :H  5      =(       a    [        R                  " U S	   U S
   :H  5      $ g )Nr   r   Tr   .r   .   ..r   .r   .r'   )r   FIRSTshapenpallLAST)r!   r"   s     r/home/james-whalen/.local/lib/python3.13/site-packages/transformers/models/lightglue/image_processing_lightglue.pyis_grayscaler2   9   s     ,222;;q>QvveFmuV}45`"&&vRWX^R_A_:``	.33	3;;r?avveFmuV}45`"&&vRWX^R_A_:`` 
4    returnc                 "   [        [        S/5        [        U [        R                  5      (       a  [        XS9(       a  U $ U[        R                  :X  a5  U S   S-  U S   S-  -   U S   S-  -   n[        R                  " U/S	-  S
S9nU$ U[        R                  :X  a3  U S   S-  U S   S-  -   U S   S-  -   n[        R                  " U/S	-  SS9nW$ [        U [        R                  R                  5      (       d  U $ U R                  S5      n U $ )aC  
Converts an image to grayscale format using the NTSC formula. Only support numpy and PIL Image. TODO support torch
and tensorflow grayscale conversion

This function is supposed to return a 1-channel image, but it returns a 3-channel image with the same value in each
channel, because of an issue that is discussed in :
https://github.com/huggingface/transformers/pull/25786#issuecomment-1730176446

Args:
    image (Image):
        The image to convert.
    input_data_format (`ChannelDimension` or `str`, *optional*):
        The channel dimension format for the input image.
visionr"   r$   gŏ1w-!?r%   gbX9?r&   gv/?r   r   )axisr)   r*   r+   r(   L)r   convert_to_grayscale
isinstancer.   ndarrayr2   r   r,   stackr0   PILr   convert)r!   r"   
gray_images      r1   r:   r:   G   s   $ *XJ7%$$CL 0 6 66v/%-&2HH5QW=[aKaaJ:,"2;J  "2"7"77v/%-&2HH5QW=[aKaaJ:,"2<JeSYY__--MM#ELr3   imagesc                   ^ SnS m[        U [        5      (       ab  [        U 5      S:X  a  [        U4S jU  5       5      (       a  U $ [        U4S jU  5       5      (       a  U  VVs/ s H  o"  H  o3PM     M     snn$ [	        U5      es  snnf )N)z-Input images must be a one of the following :z - A pair of PIL images.z - A pair of 3D arrays.z! - A list of pairs of PIL images.z  - A list of pairs of 3D arrays.c                     [        U 5      =(       dM    [        U 5      =(       a;    [        U 5      [        R                  :g  =(       a    [        U R                  5      S:H  $ )z$images is a PIL Image or a 3D array.r   )r   r   r   r   r>   lenr-   )r!   s    r1   _is_valid_image8validate_and_format_image_pairs.<locals>._is_valid_imagev   sG    E" 
5!fnU&;y}}&LfQTUZU`U`QaefQf	
r3   r'   c              3   4   >#    U  H  nT" U5      v   M     g 7fN .0r!   rE   s     r1   	<genexpr>2validate_and_format_image_pairs.<locals>.<genexpr>}   s     #Q&_U%;%;&   c              3      >#    U  HF  n[        U[        5      =(       a*    [        U5      S :H  =(       a    [        U4S jU 5       5      v   MH     g7f)r'   c              3   4   >#    U  H  nT" U5      v   M     g 7frH   rI   rJ   s     r1   rL   <validate_and_format_image_pairs.<locals>.<genexpr>.<genexpr>   s     C
uOE**
rN   N)r;   listrD   r/   )rK   
image_pairrE   s     r1   rL   rM      sO      
 %
 z4( DJ1$DC
CCD %s   AA)r;   rR   rD   r/   
ValueError)rA   error_messagerS   r!   rE   s       @r1   validate_and_format_image_pairsrV   m   s    M
 &$v;!#Q&#Q Q QM 
 %	
 
 
 -3KFj
uE
EFKK
]
## Ls   &B	)torch)backendsc                   <  ^  \ rS rSrSrS/rSS\R                  SSS4S\S\	\
\\4      S	\S
\S\S\SS4U 4S jjjr  S S\R                   S\
\\4   S\	\\\4      S\	\\\4      4S jjrSSSSSSS\R(                  S4	S\	\   S\	\
\\4      S	\	\   S
\	\   S\	\   S\	\   S\	\\\4      S\S\	\\\4      S\4S jjr S!S\S\\\\   4   S\S\\
\\R8                  4      4S jjrS\S\\
\\R8                  4      S\S   4S jrS r S\S\4S jr!Sr"U =r#$ )"LightGlueImageProcessor   a$  
Constructs a LightGlue image processor.

Args:
    do_resize (`bool`, *optional*, defaults to `True`):
        Controls whether to resize the image's (height, width) dimensions to the specified `size`. Can be overridden
        by `do_resize` in the `preprocess` method.
    size (`dict[str, int]` *optional*, defaults to `{"height": 480, "width": 640}`):
        Resolution of the output image after `resize` is applied. Only has an effect if `do_resize` is set to
        `True`. Can be overridden by `size` in the `preprocess` method.
    resample (`PILImageResampling`, *optional*, defaults to `Resampling.BILINEAR`):
        Resampling filter to use if resizing the image. Can be overridden by `resample` in the `preprocess` method.
    do_rescale (`bool`, *optional*, defaults to `True`):
        Whether to rescale the image by the specified scale `rescale_factor`. Can be overridden by `do_rescale` in
        the `preprocess` method.
    rescale_factor (`int` or `float`, *optional*, defaults to `1/255`):
        Scale factor to use if rescaling the image. Can be overridden by `rescale_factor` in the `preprocess`
        method.
    do_grayscale (`bool`, *optional*, defaults to `True`):
        Whether to convert the image to grayscale. Can be overridden by `do_grayscale` in the `preprocess` method.
pixel_valuesTNgp?	do_resizesizeresample
do_rescalerescale_factordo_grayscaler4   c                    > [         TU ]  " S0 UD6  Ub  UOSSS.n[        USS9nXl        X l        X0l        X@l        XPl        X`l        g )Ni  i  )heightwidthFdefault_to_squarerI   )	super__init__r   r]   r^   r_   r`   ra   rb   )	selfr]   r^   r_   r`   ra   rb   kwargs	__class__s	           r1   ri    LightGlueImageProcessor.__init__   sR     	"6"'tc-JTU;"	 $,(r3   r!   data_formatr"   c                 F    [        USS9n[        U4US   US   4UUS.UD6$ )a  
Resize an image.

Args:
    image (`np.ndarray`):
        Image to resize.
    size (`dict[str, int]`):
        Dictionary of the form `{"height": int, "width": int}`, specifying the size of the output image.
    data_format (`ChannelDimension` or `str`, *optional*):
        The channel dimension format of the output image. If not provided, it will be inferred from the input
        image. Can be one of:
        - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format.
        - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format.
        - `"none"` or `ChannelDimension.NONE`: image in (height, width) format.
    input_data_format (`ChannelDimension` or `str`, *optional*):
        The channel dimension format for the input image. If unset, the channel dimension format is inferred
        from the input image. Can be one of:
        - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format.
        - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format.
        - `"none"` or `ChannelDimension.NONE`: image in (height, width) format.
Frf   rd   re   )r^   rn   r"   )r   r	   )rj   r!   r^   rn   r"   rk   s         r1   r	   LightGlueImageProcessor.resize   sE    : TU;
x.$w-0#/	

 
 	
r3   return_tensorsc                 J   Ub  UOU R                   nUb  UOU R                  nUb  UOU R                  nUb  UOU R                  nUb  UOU R                  nUb  UOU R
                  n[        USS9n[        U5      n[        U5      (       d  [        S5      e[        UUUUUS9  U Vs/ s H  n[        U5      PM     nn[        US   5      (       a  U(       a  [        R                  S5        U
c  [        US   5      n
/ nU H\  nU(       a  U R!                  XXJS9nU(       a  U R#                  XU
S9nU(       a	  [%        XS	9n['        XU
S
9nUR)                  U5        M^     [+        S[-        U5      S5       Vs/ s H	  oXS-    PM     nnSU0n[/        UUS9$ s  snf s  snf )a  
Preprocess an image or batch of images.

Args:
    images (`ImageInput`):
        Image pairs to preprocess. Expects either a list of 2 images or a list of list of 2 images list with
        pixel values ranging from 0 to 255. If passing in images with pixel values between 0 and 1, set
        `do_rescale=False`.
    do_resize (`bool`, *optional*, defaults to `self.do_resize`):
        Whether to resize the image.
    size (`dict[str, int]`, *optional*, defaults to `self.size`):
        Size of the output image after `resize` has been applied. If `size["shortest_edge"]` >= 384, the image
        is resized to `(size["shortest_edge"], size["shortest_edge"])`. Otherwise, the smaller edge of the
        image will be matched to `int(size["shortest_edge"]/ crop_pct)`, after which the image is cropped to
        `(size["shortest_edge"], size["shortest_edge"])`. Only has an effect if `do_resize` is set to `True`.
    resample (`PILImageResampling`, *optional*, defaults to `self.resample`):
        Resampling filter to use if resizing the image. This can be one of `PILImageResampling`, filters. Only
        has an effect if `do_resize` is set to `True`.
    do_rescale (`bool`, *optional*, defaults to `self.do_rescale`):
        Whether to rescale the image values between [0 - 1].
    rescale_factor (`float`, *optional*, defaults to `self.rescale_factor`):
        Rescale factor to rescale the image by if `do_rescale` is set to `True`.
    do_grayscale (`bool`, *optional*, defaults to `self.do_grayscale`):
        Whether to convert the image to grayscale.
    return_tensors (`str` or `TensorType`, *optional*):
        The type of tensors to return. Can be one of:
            - Unset: Return a list of `np.ndarray`.
            - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`.
            - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`.
            - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`.
            - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`.
    data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`):
        The channel dimension format for the output image. Can be one of:
        - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format.
        - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format.
        - Unset: Use the channel dimension format of the input image.
    input_data_format (`ChannelDimension` or `str`, *optional*):
        The channel dimension format for the input image. If unset, the channel dimension format is inferred
        from the input image. Can be one of:
        - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format.
        - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format.
        - `"none"` or `ChannelDimension.NONE`: image in (height, width) format.
Frf   zkInvalid image type. Must be of type PIL.Image.Image, numpy.ndarray, torch.Tensor, tf.Tensor or jax.ndarray.)r]   r^   r_   r`   ra   r   zIt looks like you are trying to rescale already rescaled images. If the input images have pixel values between 0 and 1, set `do_rescale=False` to avoid rescaling them again.)r!   r^   r_   r"   )r!   scaler"   r7   )input_channel_dimr'   r\   )datatensor_type)r]   r_   r`   ra   rb   r^   r   rV   r   rT   r   r   r   loggerwarning_oncer   r	   rescaler:   r
   appendrangerD   r   )rj   rA   r]   r^   r_   r`   ra   rb   rq   rn   r"   rk   r!   
all_imagesiimage_pairsru   s                    r1   
preprocess"LightGlueImageProcessor.preprocess   s   t "+!6IDNN	'38#-#9Zt
+9+E4K^K^'3'?|TEVEV'tTYYTU; 18F##: 
 	&!)	
 6<<VE.'V<6!9%%*s
 $ >vay I
E%Xs5Zkl,UX/VghEe$  7<As:PQ6RS6R!!e,6RS,>BB? =6 Ts   (F;F outputstarget_sizes	thresholdc                    UR                   R                  S   [        U5      :w  a  [        S5      e[	        S U 5       5      (       d  [        S5      e[        U[        5      (       a)  [        R                  " X!R                   R                  S9nO3UR                  S   S:w  d  UR                  S   S:w  a  [        S5      eUnUR                  R                  5       nXTR                  S5      R                  SSSS5      -  nUR                  [        R                  5      n/ n[!        UR                   XQR"                  S	S	2S4   UR$                  S	S	2S4   5       Hq  u  pxpUS   S:  nUS   S:  nUS   U   nUS   U   nX   nX   n[        R&                  " UU:  US:  5      nUU   nXU      nUU   nUR)                  UUUS
.5        Ms     U$ )aa  
Converts the raw output of [`KeypointMatchingOutput`] into lists of keypoints, scores and descriptors
with coordinates absolute to the original image sizes.
Args:
    outputs ([`KeypointMatchingOutput`]):
        Raw outputs of the model.
    target_sizes (`torch.Tensor` or `list[tuple[tuple[int, int]]]`, *optional*):
        Tensor of shape `(batch_size, 2, 2)` or list of tuples of tuples (`tuple[int, int]`) containing the
        target size `(height, width)` of each image in the batch. This must be the original image size (before
        any processing).
    threshold (`float`, *optional*, defaults to 0.0):
        Threshold to filter out the matches with low scores.
Returns:
    `list[Dict]`: A list of dictionaries, each dictionary containing the keypoints in the first and second image
    of the pair, the matching scores and the matching indices.
r   zRMake sure that you pass in as many target sizes as the batch dimension of the maskc              3   >   #    U  H  n[        U5      S :H  v   M     g7f)r'   N)rD   )rK   target_sizes     r1   rL   ILightGlueImageProcessor.post_process_keypoint_matching.<locals>.<genexpr>m  s     IL[3{#q(Ls   zTEach element of target_sizes must contain the size (h, w) of each image of the batch)devicer   r'   r(   N)
keypoints0
keypoints1matching_scores)maskr-   rD   rT   r/   r;   rR   rW   tensorr   	keypointscloneflipreshapetoint32zipmatchesr   logical_andrz   )rj   r   r   r   image_pair_sizesr   results	mask_pairkeypoints_pairr   scoresmask0mask1r   r   matches0scores0valid_matchesmatched_keypoints0matched_keypoints1r   s                        r1   post_process_keypoint_matching6LightGlueImageProcessor.post_process_keypoint_matchingU  s   , <<a C$55qrrILIIIsttlD))$||LATATU!!!$)\-?-?-Ba-G j   ,%%++-	 5 5b 9 A A"aA NN	LL-	:=LL)__QT%:G<S<STUWXTX<Y;
6Iw aL1$EaL1$E'*51J'*51J~HmG "--g	.A8b=QM!+M!:!+],C!D%m4ONN"4"4'6#;
2 r3   rA   keypoint_matching_outputzImage.Imagec           	         [        U5      nU Vs/ s H  n[        U5      PM     nn[        S[        U5      S5       Vs/ s H	  oAXDS-    PM     nn/ n[	        XR5       GHt  u  pxUS   R
                  SS u  pUS   R
                  SS u  p[        R                  " [        X5      X-   S4[        R                  S9nUS   USU	2SU
24'   US   USU2U
S24'   [        R                  " U5      n[        R                  " U5      nUS   R                  S5      u  nnUS   R                  S5      u  nn[	        UUUUUS	   5       Hx  u  nnnnnU R                  U5      nUR!                  UUUU
-   U4USS
9  UR#                  US-
  US-
  US-   US-   4SS9  UR#                  UU
-   S-
  US-
  UU
-   S-   US-   4SS9  Mz     UR%                  U5        GMw     U$ s  snf s  snf )aj  
Plots the image pairs side by side with the detected keypoints as well as the matching between them.

Args:
    images (`ImageInput`):
        Image pairs to plot. Same as `LightGlueImageProcessor.preprocess`. Expects either a list of 2
        images or a list of list of 2 images list with pixel values ranging from 0 to 255.
    keypoint_matching_output (List[Dict[str, torch.Tensor]]]):
        A post processed keypoint matching output

Returns:
    `List[PIL.Image.Image]`: A list of PIL images, each containing the image pairs side by side with the detected
    keypoints as well as the matching between them.
r   r'   Nr   r   )dtyper   r   r   )fillre   black)r   )rV   r   r{   rD   r   r-   r.   zerosmaxuint8r   	fromarrayr    Drawunbind
_get_colorlineellipserz   )rj   rA   r   r!   r}   r~   r   rS   pair_outputheight0width0height1width1
plot_imageplot_image_pildrawkeypoints0_xkeypoints0_ykeypoints1_xkeypoints1_ykeypoint0_xkeypoint0_ykeypoint1_xkeypoint1_ymatching_scorecolors                             r1   visualize_keypoint_matching3LightGlueImageProcessor.visualize_keypoint_matching  s4   & 185;<VE.'V<273v;2JK2JQaa%(2JK'*;'Q#J(m11"15OG(m11"15OG3w#8&/1"MUWU]U]^J,6qMJxx&(),6qMJxx()"__Z8N>>.1D)4\)B)I)I!)L&L,)4\)B)I)I!)L&L,VYlL,TeHfWR[+{N 7		 +{V/C[Q  
 kAo{QaQ\_`Q`ahop 6)A-{Qf@TWX@XZehiZij   W NN>*7 (R8 A =Ks
   GGc                 L    [        SSU-
  -  5      n[        SU-  5      nSnX#U4$ )zMaps a score to a color.   r   r   )int)rj   scorergbs        r1   r   "LightGlueImageProcessor._get_color  s2    q5y!"eayr3   c           
         [         R                  " S[        5        [        5       (       a  SSKJn  O[        S5      e[        U5      nU Vs/ s H  n[        U5      PM     nn[        S[        U5      S5       Vs/ s H	  oQXUS-    PM     nn[        Xb5       GHU  u  pxUS   R                  SS u  pUS   R                  SS u  p[        R                  " [        X5      X-   S45      nUS   S-  USU	2SU
24'   US   S-  USU2U
S24'   UR!                  U5        UR#                  S	5        US
   R%                  S5      u  pUS   R%                  S5      u  nn[        XUUUS   5       Hm  u  nnnnnUR'                  UUU
-   /UU/UR)                  S5      " UR+                  5       5      SSS9  UR-                  UUSSS9  UR-                  UU
-   USSS9  Mo     UR/                  5         GMX     gs  snf s  snf )ad  
Plots the image pairs side by side with the detected keypoints as well as the matching between them. Requires
matplotlib to be installed.

.. deprecated::
    `plot_keypoint_matching` is deprecated and will be removed in a future version. Use `visualize_keypoint_matching` instead.

Args:
    images (`ImageInput`):
        Image pairs to plot. Same as `LightGlueImageProcessor.preprocess`. Expects either a list of 2 images or
        a list of list of 2 images list with pixel values ranging from 0 to 255.
    keypoint_matching_output ([`LightGlueKeypointMatchingOutput`]):
        Raw outputs of the model.
zx`plot_keypoint_matching` is deprecated and will be removed in transformers v. Use `visualize_keypoint_matching` instead.r   Nz@Please install matplotlib to use `plot_keypoint_matching` methodr'   r   r   g     o@offr   r   r   RdYlGng?g      ?)r   alpha	linewidthr   )cs)warningswarnFutureWarningr   matplotlib.pyplotpyplotImportErrorrV   r   r{   rD   r   r-   r.   r   r   imshowr8   r   plotget_cmapitemscattershow)rj   rA   r   pltr!   r}   r~   rS   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   s                          r1   plot_keypoint_matching.LightGlueImageProcessor.plot_keypoint_matching  s    	9	
 #$$+`aa085;<VE.'V<273v;2JK2JQaa%(2JK'*;'Q#J(m11"15OG(m11"15OG3w#8&/1"MNJ,6qME,AJxx&(),6qME,AJxx()JJz"HHUO)4\)B)I)I!)L&L)4\)B)I)I!)L&L,VYL,TeHfWR[+{N  +"67 +.,,x01D1D1FG!   K1EK&0+ANW HHJ/ (R =Ks   G3;G8)rb   r`   r]   r_   ra   r^   )NN)g        )$__name__
__module____qualname____firstlineno____doc__model_input_namesr   BILINEARboolr   dictstrr   floatri   r.   r<   r   r   r	   r,   r   r   r   r   rR   tuplerW   Tensorr   r   r   r   r   __static_attributes____classcell__)rl   s   @r1   rZ   rZ      s|   , (( )-'9'B'B '!)) tCH~&) %	)
 ) ) ) 
) )2 ?CDH%
zz%
 38n%
 eC)9$9:;	%

 $E#/?*?$@A%
T %))-15%)*.'+;?(8(>(>DHtC D>tC tCH~&	tC
 -.tC TNtC !tC tntC !sJ!78tC &tC $E#/?*?$@AtC 
tCt 	B0B JU34B 	B
 
d3$%	&BH44 #'tC,='>"?4 
m		4l5Z 5Sr 5 5r3   rZ   rH   )2r   typingr   r   numpyr.   rW   image_processing_utilsr   r   r   image_transformsr	   r
   image_utilsr   r   r   r   r   r   r   r   r   r   r   r   r   utilsr   r   r   r   utils.import_utilsr   modeling_lightgluer   r>   r   r    
get_loggerr   rw   r<   r   r2   r:   rV   rZ   __all__rI   r3   r1   <module>r      s  (  "   U U C    U T * ? $			H	%
 AEa::ac+;&; <=a  AE##c+;&; <=# #L$J $8 
:A0 A AH %
%r3   