Ë
    ÜÓ^jà4  ã                   ó"  — d dl mZ d dl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 dd	lmZmZmZmZmZmZmZmZ dd
lmZmZ ddlmZmZ erddlm Z   G d„ ded¬«      Z!d„ Z"defd„Z#	 	 dd„Z$	 	 	 	 dd„Z%e G d„ de
«      «       Z&dgZ'y)é    )ÚTYPE_CHECKINGN)ÚImageÚ	ImageDraw)Ú
functionalé   )ÚTorchvisionBackend)ÚBatchFeature)Úgroup_images_by_shapeÚreorder_images)Ú
ImageInputÚ	ImageTypeÚPILImageResamplingÚSizeDictÚget_image_typeÚis_pil_imageÚis_valid_imageÚto_numpy_array)ÚImagesKwargsÚUnpack)Ú
TensorTypeÚauto_docstringé   )ÚLightGlueKeypointMatchingOutputc                   ó   — e Zd ZU dZeed<   y)ÚLightGlueImageProcessorKwargszÀ
    do_grayscale (`bool`, *optional*, defaults to `self.do_grayscale`):
        Whether to convert the image to grayscale. Can be overridden by `do_grayscale` in the `preprocess` method.
    Údo_grayscaleN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚboolÚ__annotations__© ó    úƒ/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/transformers/models/lightglue/image_processing_lightglue.pyr   r   /   s   … ñð
 Ôr$   r   F)Útotalc                 ó¢   — t        | «      xsC t        | «      xr6 t        | «      t        j                  k7  xr t        | j                  «      dk(  S )Nr   ©r   r   r   r   ÚPILÚlenÚshape©Úimages    r%   Ú_is_valid_imager.   8   sF   € Ü˜Óò Ü�uÓÒb¤.°Ó"7¼9¿=¹=Ñ"HÒbÌSÐQV×Q\ÑQ\ÓM]ÐabÑMbðr$   Úimagesc                 óò   ‡— d}d„ Št        | t        «      rQt        | «      dk(  rt        ˆfd„| D «       «      r| S t        ˆfd„| D «       «      r| D ��cg c]  }|D ]  }|‘Œ Œ c}}S t	        |«      ‚c c}}w )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                 ó¢   — t        | «      xsC t        | «      xr6 t        | «      t        j                  k7  xr t        | j                  «      dk(  S )z$images is a PIL Image or a 3D array.r   r(   r,   s    r%   r.   z8validate_and_format_image_pairs.<locals>._is_valid_imageG   sG   € ä˜EÓ"ò 
Ü˜5Ó!Òf¤n°UÓ&;¼y¿}¹}Ñ&LÒfÔQTÐUZ×U`ÑU`ÓQaÐefÑQfð	
r$   é   c              3   ó.   •K  — | ]  } ‰|«      –— Œ y ­w©Nr#   ©Ú.0r-   r.   s     €r%   ú	<genexpr>z2validate_and_format_image_pairs.<locals>.<genexpr>N   s   øè ø€ Ò#QÀ¡_°U×%;Ñ#Qùó   ƒc              3   óŠ   •K  — | ]:  }t        |t        «      xr$ t        |«      d k(  xr t        ˆfd„|D «       «      –— Œ< y­w)r2   c              3   ó.   •K  — | ]  } ‰|«      –— Œ y ­wr4   r#   r5   s     €r%   r7   z<validate_and_format_image_pairs.<locals>.<genexpr>.<genexpr>S   s   øè ø€ ÒC¨u‘O E×*ÑCùr8   N)Ú
isinstanceÚlistr*   Úall)r6   Ú
image_pairr.   s     €r%   r7   z2validate_and_format_image_pairs.<locals>.<genexpr>P   sN   øè ø€ ò 
ð ô �z¤4Ó(ò DÜ�J“ 1Ñ$òDäÓC¸
ÔCÓCóDñ
ùs   ƒA A)r;   r<   r*   r=   Ú
ValueError)r/   Úerror_messager>   r-   r.   s       @r%   Úvalidate_and_format_image_pairsrA   >   s€   ø€ ð€Mò
ô �&œ$ÔÜˆv‹;˜!Ò¤Ó#QÈ&Ô#QÔ QØˆMÜó 
ð %ô	
ô 
ð -3×K˜jÀ
ÒK°u’EÐK�EÓKÐKÜ
�]Ó
#Ð#ùó Ls   ÁA3c           	      ó$  — | j                   dk  s#| j                  | j                   dk(  rdnd   dk(  ryt        j                  | dddd…dd…f   | dddd…dd…f   k(  «      xr. t        j                  | dddd…dd…f   | dddd…dd…f   k(  «      S )zAChecks if an image is grayscale (all RGB channels are identical).r   r   r   T.Nr2   )Úndimr+   Útorchr=   r,   s    r%   Úis_grayscalerE   Z   s‘   € ð ‡z�z�A‚~˜Ÿ™¨%¯*©*¸ª/¡Q¸qÑAÀQÒFØÜ�9‰9�U˜3 ¢1¢a˜<Ñ(¨E°#°qº!ºQ°,Ñ,?Ñ?Ó@ò ÄUÇYÁYØˆc�1’ašˆlÑ˜u S¨!ªQ² \Ñ2Ñ2óFð r$   c                 óJ   — t        | «      r| S t        j                  | d¬«      S )a±  
    Converts an image to grayscale format using the NTSC formula. Only support torch.Tensor.

    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 (torch.Tensor):
            The image to convert.
    r   )Únum_output_channels)rE   ÚtvFÚrgb_to_grayscaler,   s    r%   Úconvert_to_grayscalerJ   e   s$   € ô �EÔØˆÜ×Ñ ¸1Ô=Ð=r$   c                   óx  ‡ — e Zd ZeZej                  ZdddœZdZ	dZ
dZdZdZdZdee   fˆ fd	„Zed
edee   defˆ fd„«       Zd
edefd„Z	 d"d
ed   dededddedededz  deez  dz  dedefd„Z	 d#dddeee   z  dedeeeej@                  f      fd„Z!deeeej@                  f      ded   fd „Z"d!„ Z#ˆ xZ$S )$ÚLightGlueImageProcessorià  i€  )ÚheightÚwidthFTgp?NÚkwargsc                 ó$   •— t        ‰| �  di |¤Ž y )Nr#   )ÚsuperÚ__init__)ÚselfrO   Ú	__class__s     €r%   rR   z LightGlueImageProcessor.__init__„   s   ø€ Ü‰ÑÑ"˜6Ó"r$   r/   Úreturnc                 ó$   •— t        ‰| �  |fi |¤ŽS r4   )rQ   Ú
preprocess)rS   r/   rO   rT   s      €r%   rW   z"LightGlueImageProcessor.preprocess‡   s   ø€ ä‰wÑ! &Ñ3¨FÑ3Ð3r$   c                 ó:   — | j                  |«      }t        |«      S r4   )Úfetch_imagesrA   )rS   r/   rO   s      r%   Ú_prepare_images_structurez1LightGlueImageProcessor._prepare_images_structure‹   s   € ð ×"Ñ" 6Ó*ˆÜ.¨vÓ6Ð6r$   útorch.TensorÚ	do_resizeÚsizeÚresamplez7PILImageResampling | tvF.InterpolationMode | int | NoneÚ
do_rescaleÚrescale_factorÚdisable_groupingÚreturn_tensorsr   c
                 ó(  — t        ||¬«      \  }}i }|j                  «       D ]   \  }}|r| j                  |||¬«      }|||<   Œ" t        ||«      }t        ||¬«      \  }}i }|j                  «       D ]+  \  }}|r| j	                  ||«      }|	rt        |«      }|||<   Œ- t        ||«      }t        dt        |«      d«      D �cg c]
  }|||dz    ‘Œ }}|D �cg c]  }t        j                  |d¬«      ‘Œ }}t        d|i|¬«      S c c}w c c}w )N)ra   )r]   r^   r   r2   )ÚdimÚpixel_values)ÚdataÚtensor_type)r
   ÚitemsÚresizer   ÚrescalerJ   Úranger*   rD   Ústackr	   )rS   r/   r\   r]   r^   r_   r`   ra   rb   r   rO   Úgrouped_imagesÚgrouped_images_indexÚprocessed_images_groupedr+   Ústacked_imagesÚresized_imagesÚprocessed_imagesÚiÚimage_pairsÚpairÚstacked_pairss                         r%   Ú_preprocessz#LightGlueImageProcessor._preprocess”   sS  € ô 0EÀVÐ^nÔ/oÑ,ˆÐ,Ø#%Ð à%3×%9Ñ%9Ó%;ò 	=Ñ!ˆE�>ÙØ!%§¡¨^À$ÐQY Ó!Z�Ø.<Ð$ UÒ+ð	=ô (Ð(@ÐBVÓWˆä/DÀ^ÐfvÔ/wÑ,ˆÐ,Ø#%Ð Ø%3×%9Ñ%9Ó%;ò 	=Ñ!ˆE�>ÙØ!%§¡¨n¸nÓ!M�ÙÜ!5°nÓ!E�Ø.<Ð$ UÒ+ð	=ô *Ð*BÐDXÓYÐô =BÀ!ÄSÐIYÓEZÐ\]Ó<^Ö_°qÐ'¨¨A°©EÒ2Ð_ˆÐ_ð ?JÖJ°dœŸ™ T¨qÖ1ÐJˆÐJô  .°-Ð!@ÈnÔ]Ð]ùò `ùò Ks   ÃD
ÃDÚoutputsr   Útarget_sizesÚ	thresholdc                 ó¢  — |j                   j                  d   t        |«      k7  rt        d«      ‚t	        d„ |D «       «      st        d«      ‚t        |t        «      r,t        j                  ||j                   j                  ¬«      }n1|j                  d   dk7  s|j                  d   dk7  rt        d«      ‚|}|j                  j                  «       }||j                  d«      j                  dddd«      z  }|j                  t        j                  «      }g }t!        |j                   ||j"                  d	d	…df   |j$                  d	d	…df   «      D ]v  \  }}}	}
|d   dkD  }|d   dkD  }|d   |   }|d   |   }|	|   }|
|   }||kD  |dkD  z  ||j                  d   k  z  }||   }|||      }||   }|j'                  |||d
œ«       Œx |S )aí  
        Converts the raw output of [`LightGlueKeypointMatchingOutput`] into lists of keypoints, scores and descriptors
        with coordinates absolute to the original image sizes.
        Args:
            outputs ([`LightGlueKeypointMatchingOutput`]):
                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   ó8   K  — | ]  }t        |«      d k(  –— Œ y­w)r2   N)r*   )r6   Útarget_sizes     r%   r7   zILightGlueImageProcessor.post_process_keypoint_matching.<locals>.<genexpr>×   s   è ø€ ÒI¨[”3�{Ó# qÕ(ÑIùs   ‚zTEach element of target_sizes must contain the size (h, w) of each image of the batch)Údevicer   r2   éÿÿÿÿN)Ú
keypoints0Ú
keypoints1Úmatching_scores)Úmaskr+   r*   r?   r=   r;   r<   rD   Útensorr~   Ú	keypointsÚcloneÚflipÚreshapeÚtoÚint32ÚzipÚmatchesr‚   Úappend)rS   rx   ry   rz   Úimage_pair_sizesr…   ÚresultsÚ	mask_pairÚkeypoints_pairrŒ   ÚscoresÚmask0Úmask1r€   r�   Úmatches0Úscores0Úvalid_matchesÚmatched_keypoints0Úmatched_keypoints1r‚   s                        r%   Úpost_process_keypoint_matchingz6LightGlueImageProcessor.post_process_keypoint_matching¿   s  € ð, �<‰<×Ñ˜aÑ ¤C¨Ó$5Ò5ÜÐqÓrÐrÜÑI¸LÔIÔIÜÐsÓtÐtä�l¤DÔ)Ü$Ÿ|™|¨LÀÇÁ×ATÑATÔUÑà×!Ñ! !Ñ$¨Ò)¨\×-?Ñ-?ÀÑ-BÀaÒ-GÜ Øjóð ð  ,Ðà×%Ñ%×+Ñ+Ó-ˆ	ØÐ 0× 5Ñ 5°bÓ 9× AÑ AÀ"ÀaÈÈAÓ NÑNˆ	Ø—L‘L¤§¡Ó-ˆ	àˆÜ:=Ø�L‰L˜) W§_¡_²Q¸°TÑ%:¸G×<SÑ<SÒTUÐWXÐTXÑ<Yó;
ò 	Ñ6ˆI�~ w°ð ˜a‘L 1Ñ$ˆEØ˜a‘L 1Ñ$ˆEØ'¨Ñ*¨5Ñ1ˆJØ'¨Ñ*¨5Ñ1ˆJØ˜u‘~ˆHØ˜U‘mˆGð % yÑ0°XÀ±]ÑCÀxÐR\×RbÑRbÐcdÑReÑGeÑfˆMà!+¨MÑ!:ÐØ!+¨H°]Ñ,CÑ!DÐØ% mÑ4ˆOà�N‰Nà"4Ø"4Ø'6ñõð#	ð2 ˆr$   Úkeypoint_matching_outputzImage.Imagec           	      ó<  — t        |«      }|D �cg c]  }t        |«      ‘Œ }}t        dt        |«      d«      D �cg c]
  }|||dz    ‘Œ }}g }t	        ||«      D �]³  \  }}|d   j
                  dd \  }	}
|d   j
                  dd \  }}t        j                  t        |	|«      |
|z   dft        j                  ¬«      }t        j                  |d   «      |d|	…d|
…f<   t        j                  |d   «      |d|…|
d…f<   t        j                  |j                  «       «      }t        j                  |«      }|d   j!                  d«      \  }}|d   j!                  d«      \  }}t	        |||||d	   «      D ]€  \  }}}}}| j#                  |«      }|j%                  ||||
z   |f|d¬
«       |j'                  |dz
  |dz
  |dz   |dz   fd¬«       |j'                  ||
z   dz
  |dz
  ||
z   dz   |dz   fd¬«       Œ‚ |j)                  |«       �Œ¶ |S c c}w c c}w )a¸  
        Plots the image pairs side by side with the detected keypoints as well as the matching between them.

        Args:
            images:
                Image pairs to plot. Same as `EfficientLoFTRImageProcessor.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   r2   Nr   r   )Údtyper€   r�   r‚   )ÚfillrN   Úblack)rž   )rA   r   rk   r*   r‹   r+   rD   ÚzerosÚmaxÚuint8Ú
from_numpyr   Ú	fromarrayÚnumpyr   ÚDrawÚunbindÚ
_get_colorÚlineÚellipser�   )rS   r/   r›   r-   rs   rt   r�   r>   Ú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                             r%   Úvisualize_keypoint_matchingz3LightGlueImageProcessor.visualize_keypoint_matching  sh  € ô( 1°Ó8ˆØ5;Ö<¨E”. Õ'Ð<ˆÐ<Ü27¸¼3¸v»;ÈÓ2JÖK¨Q�v˜a ! a¡%Ò(ÐKˆÐKàˆÜ'*¨;Ð8PÓ'Qó 	+Ñ#ˆJ˜Ø(¨™m×1Ñ1°"°1Ð5‰OˆG�VØ(¨™m×1Ñ1°"°1Ð5‰OˆG�VÜŸ™¤c¨'°7Ó&;¸VÀf¹_ÈaÐ%PÔX]×XcÑXcÔdˆJÜ,1×,<Ñ,<¸ZÈ¹]Ó,KˆJ�x˜�x  & Ð(Ñ)Ü,1×,<Ñ,<¸ZÈ¹]Ó,KˆJ�x˜�x ¡Ð(Ñ)ä"Ÿ_™_¨Z×-=Ñ-=Ó-?Ó@ˆNÜ—>‘> .Ó1ˆDà)4°\Ñ)B×)IÑ)IÈ!Ó)LÑ&ˆL˜,Ø)4°\Ñ)B×)IÑ)IÈ!Ó)LÑ&ˆL˜,ÜVYØ˜l¨L¸,ÈÐTeÑHfóWò ÑR�˜[¨+°{ÀNð Ÿ™¨Ó7�Ø—	‘	Ø  +¨{¸VÑ/CÀ[ÐQØØð ô ð
 —‘˜k¨A™o¨{¸Q©ÀÈaÁÐQ\Ð_`ÑQ`ÐaÐho�ÔpØ—‘Ø  6Ñ)¨AÑ-¨{¸Q©ÀÈfÑ@TÐWXÑ@XÐZeÐhiÑZiÐjØ ð õ ðð �N‰N˜>Ö*ð7	+ð8 ˆùòA =ùÚKs
   �H¼Hc                 óN   — t        dd|z
  z  «      }t        d|z  «      }d}|||fS )zMaps a score to a color.éÿ   r   r   )Úint)rS   ÚscoreÚrÚgÚbs        r%   r¨   z"LightGlueImageProcessor._get_color:  s3   € ä��q˜5‘yÑ!Ó"ˆÜ��e‘ÓˆØˆØ�!�Qˆwˆr$   )T)g        )%r   r   r   r   Úvalid_kwargsr   ÚBILINEARr^   r]   Údefault_to_squarer\   r_   r`   Údo_normalizer   r   rR   r   r   r	   rW   rZ   r<   r!   r   ÚfloatÚstrr   rw   ÚtupleÚdictrD   ÚTensorrš   r½   r¨   Ú__classcell__)rT   s   @r%   rL   rL   x   sª  ø„ à0€LØ!×*Ñ*€HØ CÑ(€DØÐØ€IØ€JØ€NØ€LØ€Lð# Ð(EÑ!Fõ #ð ð4 ð 4°vÐ>[Ñ7\ð 4Ðamô 4ó ð4ð7àð7ð 
ó	7ð& "ñ)^à�^Ñ$ð)^ð ð)^ð ð	)^ð
 Lð)^ð ð)^ð ð)^ð  ™+ð)^ð ˜jÑ(¨4Ñ/ð)^ð ð)^ð 
ó)^ð^ ñ	Bà2ðBð ! 4¨¡;Ñ.ðBð ð	Bð
 
ˆd�3˜Ÿ™Ð$Ñ%Ñ	&óBðH5ð #' t¨C°·±Ð,=Ñ'>Ñ"?ð5ð 
ˆmÑ	ó	5önr$   rL   )r-   r[   )r-   r[   rU   r[   )(Útypingr   rD   r)   r   r   Útorchvision.transforms.v2r   rH   Úimage_processing_backendsr   Úimage_processing_utilsr	   Úimage_transformsr
   r   Úimage_utilsr   r   r   r   r   r   r   r   Úprocessing_utilsr   r   Úutilsr   r   Úmodeling_lightgluer   r   r.   rA   rE   rJ   rL   Ú__all__r#   r$   r%   ú<module>rÙ      s¦   ðõ( !ã ß  Ý 7å ;Ý 2ß E÷	÷ 	ó 	÷ 5ß /ñ ÝCô L¸õ òð$¨Jó $ð8Øóð>Øð>àó>ð& ôFÐ0ó Fó ðFðR %Ð
%�r$   