o
    ॵi)                     @   s   d dl mZmZmZmZ d dlZd dlZd dlZd dl	Z	d dl
mZ d dlmZ d dlmZmZmZ d dlmZ d dlmZ d dlmZ d d	lmZ e Zejejejd
G dd deZdS )    )AnyDictListUnionN)	Pipelines)
OutputKeys)InputModelPipeline)	PIPELINES)	LoadImage)Tasks)
get_logger)module_namec                       s   e Zd ZdZdef fddZdd Zdd ZdddZdd Z	dde
fddZdd Zdeeef deeef fddZdeeef deeef fddZ fddZ  ZS )ImageMatchingPipelinea   Image Matching Pipeline.

    Examples:

    >>> from modelscope.outputs import OutputKeys
    >>> from modelscope.pipelines import pipeline
    >>> from modelscope.utils.constant import Tasks


    >>> task = 'image-matching'
    >>> model_id = 'damo/cv_quadtree_attention_image-matching_outdoor'

    >>> input_location = [
    >>>                     ['data/test/images/image_matching1.jpg',
    >>>                     'data/test/images/image_matching2.jpg']
    >>>                 ]
    >>> estimator = pipeline(Tasks.image_matching, model=self.model_id)
    >>> result = estimator(input_location)
    >>> kpts0, kpts1, conf = result[0][OutputKeys.MATCHES]
    >>> print(f'Found {len(kpts0)} matches')
    modelc                    s6   t  jdd|i| tj stdtd dS )z
        use `model` to create a image matching pipeline for prediction
        Args:
            model: model id on modelscope hub.
        r   z?Cuda is not available. Image matching model only supports cuda.z#image matching model, pipeline initN )super__init__torchcudais_availableRuntimeErrorloggerinfo)selfr   kwargs	__class__r   c/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/pipelines/cv/image_matching_pipeline.pyr   -   s   
zImageMatchingPipeline.__init__c                 C   sj   |j d d \}}d}t|||kr1|t|| }t|| t|| }}tj|||ftjd}||fS )N      )interpolation)shapemaxintcv2resize
INTER_AREA)r   imgmax_image_sizehwscalenew_wnew_hr   r   r   resize_image=   s   z"ImageMatchingPipeline.resize_imagec                 C   s   t t|| | S N)r%   npceil)r   sizedivr   r   r   compute_paded_sizeF   s   z(ImageMatchingPipeline.compute_paded_sizeN    c           	   	   C   sl   |j d d \}}|d u r|d u r||}}| ||| ||}}tj|d|| d|| tjdd}|S )Nr    r   )value)r#   r6   r&   copyMakeBorderBORDER_CONSTANT)	r   r)   r+   r,   r5   cur_hcur_wh_padw_padr   r   r   	pad_imageI   s(   
zImageMatchingPipeline.pad_imagec                 C   s:   t |tj}|d }t|jdkrt|tj	}|S )Ng     o@   )
r   convert_to_ndarrayastyper2   float32lenr#   r&   cvtColorCOLOR_RGB2GRAY)r   img_namer)   r   r   r   
load_imageZ   s
   z ImageMatchingPipeline.load_image   inputc                 C   s   t |dks
J d| |d }| ||\}}|jd d \}}| |d }| ||\}}|jd d \}	}
t||	t||
}}| |||}| |||}t|d  d   	 }t|d  d   	 }|||||||	|
gdS )Nr    z$input should be a list of two imagesr   r!   )image0image1preprocess_info)
rD   rH   r0   r#   r$   r?   r   
from_numpyr   float)r   rJ   r*   img1scale1	scaled_h1	scaled_w1img2scale2	scaled_h2	scaled_w2h_maxw_maxr   r   r   
preprocessb   s    z ImageMatchingPipeline.preprocessc
                 C   s   |d d df |k |d d df |k @ |d d df |	k @ |d d df |k @ }
||
 ||
 }}|| }|| }||
 }|||fS )Nr   r!   r   )r   kpt1kpt2confrQ   rU   rR   rS   rV   rW   valid_matchr   r   r   postprocess_match|   s   &
z'ImageMatchingPipeline.postprocess_matchreturnc                 C   s   | j |}|S r1   )r   	inference)r   rJ   resultsr   r   r   forward   s   zImageMatchingPipeline.forwardinputsc           	      C   s   | j |}|tj }|d   }|d   }|d   }dd |d D }| j|||g|R  \}}}tj|||gi}|S )Nkpts0kpts1r]   c                 S   s   g | ]}|   qS r   )cpunumpy).0vr   r   r   
<listcomp>   s    z5ImageMatchingPipeline.postprocess.<locals>.<listcomp>rM   )r   postprocessr   MATCHESrg   rh   r_   )	r   rd   rb   matchesre   rf   r]   rM   outputsr   r   r   rl      s   
z!ImageMatchingPipeline.postprocessc                    s   t  j|fi |S )a  
        Match two images and return the matched keypoints and confidence.

        Args:
            input (`List[List[str]]`): A list of two image paths.

        Return:
            A list of result.
            The list contain the following values:

            - kpts0 -- Matched keypoints in the first image
            - kpts1 -- Matched keypoints in the second image
            - conf -- Confidence of the match
        )r   __call__)r   rJ   r   r   r   r   rp      s   zImageMatchingPipeline.__call__)NNr7   )rI   )__name__
__module____qualname____doc__strr   r0   r6   r?   rH   r   rZ   r_   r   r   rc   rl   rp   __classcell__r   r   r   r   r      s    	
""r   )typingr   r   r   r   r&   rh   r2   PILr   modelscope.metainfor   modelscope.outputsr   modelscope.pipelines.baser   r	   r
   modelscope.pipelines.builderr   modelscope.preprocessorsr   modelscope.utils.constantr   modelscope.utils.loggerr   r   register_moduleimage_matchingr   r   r   r   r   <module>   s"   