ó
    qyüi–1  ã                   óH  • S SK Jr  S SKJrJr  S SKJr  SSKJ	r	  SSK
Jr  SSKJrJr  SSKJrJrJrJrJrJrJrJr  SS	KJrJr  SS
KJrJrJr  \" 5       (       a  S SKr\(       a  SSK J!r!   " S S\SS9r"S r#S\4S jr$  SS jr%    SS jr&\ " S S\	5      5       r'S/r(g)é    )ÚTYPE_CHECKING)Ú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Úis_torch_availableNé   )Ú$EfficientLoFTRKeypointMatchingOutputc                   ó$   • \ rS rSr% Sr\\S'   Srg)Ú"EfficientLoFTRImageProcessorKwargsé$   z´
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_grayscale© N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__ÚboolÚ__annotations__Ú__static_attributes__r   ó    Ú/home/mande/repo/quber/.venv/lib/python3.13/site-packages/transformers/models/efficientloftr/image_processing_efficientloftr.pyr   r   $   s   ‡ ñð
 Ör(   r   F)Útotalc                 óÀ   • [        U 5      =(       dM    [        U 5      =(       a;    [        U 5      [        R                  :g  =(       a    [        U R                  5      S:H  $ )Nr   ©r   r   r   r   ÚPILÚlenÚshape©Úimages    r)   Ú_is_valid_imager2   -   sF   € Ü˜Ó÷ Ü�uÓ×b¤.°Ó"7¼9¿=¹=Ñ"H×bÌSÐQV×Q\ÑQ\ÓM]ÐabÑMbðr(   Ú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,   r0   s    r)   r2   Ú8validate_and_format_image_pairs.<locals>._is_valid_image<   sG   € ä˜EÓ"÷ 
Ü˜5Ó!×f¤n°UÓ&;¼y¿}¹}Ñ&L×fÔQTÐUZ×U`ÑU`ÓQaÐefÑQfð	
r(   é   c              3   ó4   >#   • U  H  nT" U5      v •  M     g 7f©Nr   ©Ú.0r1   r2   s     €r)   Ú	<genexpr>Ú2validate_and_format_image_pairs.<locals>.<genexpr>C   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)r7   c              3   ó4   >#   • U  H  nT" U5      v •  M     g 7fr9   r   r:   s     €r)   r<   Ú<validate_and_format_image_pairs.<locals>.<genexpr>.<genexpr>H   s   øé € ÐCº
¨u‘O E×*Ð*º
ùr>   N)Ú
isinstanceÚlistr.   Úall)r;   Ú
image_pairr2   s     €r)   r<   r=   E   sO   øé € ð 
ò %�
ô �z¤4Ó(÷ DÜ�J“ 1Ñ$÷DäÔC¹
ÓCÓCôDò %ùs   ƒAA)rB   rC   r.   rD   Ú
ValueError)r3   Úerror_messagerE   r1   r2   s       @r)   Úvalidate_and_format_image_pairsrH   3   s‹   ø€ ð€Mò
ô �&œ$×ÑÜˆv‹;˜!Ó¤Ô#QÉ&Ó#Q× QÑ QØˆMÜô 
ñ %ó	
÷ 
ñ 
ñ -3ÔKªF˜jÃ
°u’EÁ
‘E©FÒKÐKÜ
�]Ó
#Ð#ùó Ls   Á&B	c           	      ó8  • U R                   S:  d%  U R                  U R                   S:X  a  SOS   S:X  a  g[        R                  " U SSSS2SS24   U SSSS2SS24   :H  5      =(       a/    [        R                  " U SSSS2SS24   U SSSS2SS24   :H  5      $ )zAChecks if an image is grayscale (all RGB channels are identical).r   r   r   T.Nr7   )Úndimr/   ÚtorchrD   r0   s    r)   Úis_grayscalerL   O   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                 óP   • [        U 5      (       a  U $ [        R                  " U SS9$ )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)rL   ÚtvFÚrgb_to_grayscaler0   s    r)   Úconvert_to_grayscalerQ   Z   s'   € ô �E×ÑØˆÜ×Ò ¸1Ñ=Ð=r(   c                   ó”  ^ • \ rS rSr\r\R                  rSSS.r	Sr
SrSrSrSrSrS	\\   4U 4S
 jjr\S\S	\\   S\4U 4S jj5       rS\S\4S jr S$S\S   S\S\SSS\S\S\S-  S\\-  S-  S\S\4S jjr S%SSS\\\   -  S\S\\\\ RB                  4      4S jjr"S\\\\ RB                  4      S\S    4S! jr#S" r$S#r%U =r&$ )&ÚEfficientLoFTRImageProcessorém   ià  i€  )ÚheightÚwidthFTgp?NÚkwargsc                 ó&   >• [         TU ]  " S0 UD6  g )Nr   )ÚsuperÚ__init__)ÚselfrW   Ú	__class__s     €r)   rZ   Ú%EfficientLoFTRImageProcessor.__init__y   s   ø€ Ü‰ÒÑ"˜6Ó"r(   r3   Úreturnc                 ó&   >• [         TU ]  " U40 UD6$ r9   )rY   Ú
preprocess)r[   r3   rW   r\   s      €r)   r`   Ú'EfficientLoFTRImageProcessor.preprocess|   s   ø€ ä‰wÒ! &Ñ3¨FÑ3Ð3r(   c                 ó:   • U R                  U5      n[        U5      $ r9   )Úfetch_imagesrH   )r[   r3   rW   s      r)   Ú_prepare_images_structureÚ6EfficientLoFTRImageProcessor._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
                 ó(  • [        XS9u  p¼0 nUR                  5        H   u  pïU(       a  U R                  XóUS9nXýU'   M"     [        XÜ5      n[        UUS9u  p¼0 nUR                  5        H3  u  pïU(       a  U R	                  Xö5      nU	(       a  [        U5      nXýU'   M5     [        XÜ5      n[        S[        U5      S5       Vs/ s H  nUUUS-    PM     nnU Vs/ s H  n[        R                  " USS9PM     nn[        SU0US9$ s  snf s  snf )N)rl   )rh   ri   r   r7   )ÚdimÚpixel_values)ÚdataÚtensor_type)r
   ÚitemsÚresizer   ÚrescalerQ   Úranger.   rK   Ústackr	   )r[   r3   rg   rh   ri   rj   rk   rl   rm   r   rW   Úgrouped_imagesÚgrouped_images_indexÚprocessed_images_groupedr/   Ústacked_imagesÚresized_imagesÚprocessed_imagesÚiÚimage_pairsÚpairÚstacked_pairss                         r)   Ú_preprocessÚ(EfficientLoFTRImageProcessor._preprocess‰   s0  € ô 0EÀVÑ/oÑ,ˆØ#%Ð à%3×%9Ñ%9Ö%;Ñ!ˆEÞØ!%§¡¨^ÐQY Ð!Z�Ø.< UÓ+ñ &<ô (Ð(@ÓWˆä/DÀ^ÐfvÑ/wÑ,ˆØ#%Ð Ø%3×%9Ñ%9Ö%;Ñ!ˆEÞØ!%§¡¨nÓ!M�ÞÜ!5°nÓ!E�Ø.< UÓ+ñ &<ô *Ð*BÓYÐô =BÀ!ÄSÐIYÓEZÐ\]Ô<^Ó_Ò<^°qÐ'¨¨A°©EÓ2Ñ<^ˆÐ_ñ ?JÓJºk°dœŸš T¨qÔ1¹kˆÐJô  .°-Ð!@ÈnÑ]Ð]ùò `ùò Ks   ÃD
ÃDÚoutputsr   Útarget_sizesÚ	thresholdc                 óF  • 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[!        XQR                   UR"                  5       HX  u  pxn	[        R$                  " X“:„  US:„  5      n
US   U
S      nUS   U
S      nU	S   U
S      nUR'                  UUUS	.5        MZ     U$ )
a}  
Converts the raw output of [`EfficientLoFTRKeypointMatchingOutput`] into lists of keypoints, scores and descriptors
with coordinates absolute to the original image sizes.
Args:
    outputs ([`EfficientLoFTRKeypointMatchingOutput`]):
        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)r7   N)r.   )r;   Útarget_sizes     r)   r<   ÚNEfficientLoFTRImageProcessor.post_process_keypoint_matching.<locals>.<genexpr>Ì   s   é € ÐIºL¨[”3�{Ó# qÖ(ºLùs   ‚zTEach element of target_sizes must contain the size (h, w) of each image of the batch)Údevicer   r7   éÿÿÿÿ)Ú
keypoints0Ú
keypoints1Úmatching_scores)Úmatchesr/   r.   rF   rD   rB   rC   rK   Útensorr‹   Ú	keypointsÚcloneÚflipÚreshapeÚtoÚint32Úzipr�   Úlogical_andÚappend)r[   r„   r…   r†   Úimage_pair_sizesr’   ÚresultsÚkeypoints_pairr�   ÚscoresÚvalid_matchesÚmatched_keypoints0Úmatched_keypoints1r�   s                 r)   Úpost_process_keypoint_matchingÚ;EfficientLoFTRImageProcessor.post_process_keypoint_matching´   s“  € ð, �?‰?× Ñ  Ñ#¤s¨<Ó'8Ó8ÜÐqÓrÐrÜÑI¹LÓI×IÑIÜÐsÓtÐtä�l¤D×)Ñ)Ü$Ÿ|š|¨LÇÁ×AWÑAWÑXÑà×!Ñ! !Ñ$¨Ó)¨\×-?Ñ-?ÀÑ-BÀaÓ-GÜ Øjóð ð  ,Ðà×%Ñ%×+Ñ+Ó-ˆ	Ø× 5Ñ 5°bÓ 9× AÑ AÀ"ÀaÈÈAÓ NÑNˆ	Ø—L‘L¤§¡Ó-ˆ	àˆÜ/2°9¿o¹oÈw×OfÑOfÖ/gÑ+ˆN Vä!×-Ò-¨fÑ.@À'ÈBÁ,ÓOˆMà!/°Ñ!2°=ÀÑ3CÑ!DÐØ!/°Ñ!2°=ÀÑ3CÑ!DÐØ$ Q™i¨°aÑ(8Ñ9ˆOà�N‰Nà"4Ø"4Ø'6ñöñ 0hð  ˆr(   Úkeypoint_matching_outputzImage.Imagec           	      ó2  • [        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Hª  u  pxUS   R
                  SS u  pšUS   R
                  SS u  p¼[        R                  " [        X›5      X¬-   S4[        R                  S9n[        R                  " US   5      USU	2SU
24'   [        R                  " US   5      USU2U
S24'   [        R                  " UR                  5       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M­     U$ s  snf s  snf )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   r7   Nr   r   )Údtyper�   rŽ   r�   )ÚfillrV   Úblack)r§   )rH   r   rv   r.   r˜   r/   rK   ÚzerosÚmaxÚuint8Ú
from_numpyr   Ú	fromarrayÚnumpyr   ÚDrawÚunbindÚ
_get_colorÚlineÚellipserš   )r[   r3   r¤   r1   r~   r   rœ   rE   Ú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_matchingÚ8EfficientLoFTRImageProcessor.visualize_keypoint_matchingï   sS  € ô( 1°Ó8ˆÙ5;Ó<²V¨E”. Ö'±VˆÐ<Ü27¸¼3¸v»;ÈÔ2JÓKÒ2J¨Q˜a a¡%Ó(Ñ2JˆÐKàˆÜ'*¨;×'QÑ#ˆJØ(¨™m×1Ñ1°"°1Ð5‰OˆGØ(¨™m×1Ñ1°"°1Ð5‰OˆGÜŸš¤c¨'Ó&;¸V¹_È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Ø ð ó ñWð �N‰N˜>×*ñ7 (Rð8 ˆùòA =ùÚKs
   �H¿H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)r[   ÚscoreÚrÚgÚbs        r)   r±   Ú'EfficientLoFTRImageProcessor._get_color&  s1   € ä��q˜5‘yÑ!Ó"ˆÜ��e‘ÓˆØˆØ�Qˆwˆr(   r   )T)g        )'r    r!   r"   r#   r   Úvalid_kwargsr   ÚBILINEARri   rh   Údefault_to_squarerg   rj   rk   Údo_normalizer   r   rZ   r   r   r	   r`   rd   rC   r%   r   ÚfloatÚstrr   r‚   ÚtupleÚdictrK   ÚTensorr¢   rÆ   r±   r'   Ú__classcell__)r\   s   @r)   rS   rS   m   sª  ø† à5€LØ!×*Ñ*€HØ CÑ(€DØÐØ€IØ€JØ€NØ€LØ€Lð# Ð(JÑ!K÷ #ð ð4 ð 4°vÐ>`Ñ7að 4Ðfrö 4ó ð4ð7àð7ð 
ô	7ð& "ñ)^à�^Ñ$ð)^ð ð)^ð ð	)^ð
 Lð)^ð ð)^ð ð)^ð  ™+ð)^ð ˜jÑ(¨4Ñ/ð)^ð ð)^ð 
õ)^ð^ ñ	9à7ð9ð ! 4¨¡;Ñ.ð9ð ð	9ð
 
ˆd�3˜Ÿ™Ð$Ñ%Ñ	&õ9ðv5ð #' t¨C°·±Ð,=Ñ'>Ñ"?ð5ð 
ˆmÑ	ô	5÷nð r(   rS   )r1   rf   )r1   rf   r^   rf   ))Útypingr   r-   r   r   Útorchvision.transforms.v2r   rO   Úimage_processing_backendsr   Úimage_processing_utilsr	   Úimage_transformsr
   r   Úimage_utilsr   r   r   r   r   r   r   r   Úprocessing_utilsr   r   Úutilsr   r   r   rK   Úmodeling_efficientloftrr   r   r2   rH   rL   rQ   rS   Ú__all__r   r(   r)   Ú<module>rä      s²   ðõ !ç  Ý 7å ;Ý 2ß E÷	÷ 	ó 	÷ 5ß CÑ Cñ ×ÑÛæÝMô¨¸Uò òð$¨Jô $ð8Øôð>Øð>àô>ð& ô}Ð#5ó }ó ð}ð@ *Ð
*�r(   