a
    d%                     @   st   d Z ddlZddlmZmZ ddlZddlmZ ddlm	Z	m
Z
mZmZ ddlmZmZ dgZG dd dejZdS )z!Module containing RANSAC modules.    N)OptionalTuple)find_fundamentalfind_homography_dltfind_homography_dlt_iteratedsymmetrical_epipolar_distance)oneway_transfer_errorsample_is_valid_for_homographyRANSACc                       s8  e Zd ZdZddgZd%eeeeeed	 fd
dZe	
dfeeee	j
e	jdddZeeeeeedddZe	je	je	jdddZe	je	je	jeee	je	jef dddZe	je	jee	je	jf dddZe	je	jdddZe	je	je	je	jddd Zd&e	je	jee	j ee	je	jf d"d#d$Z  ZS )'r
   at  Module for robust geometry estimation with RANSAC.

    https://en.wikipedia.org/wiki/Random_sample_consensus

    Args:
        model_type: type of model to estimate, e.g. "homography" or "fundamental".
        inliers_threshold: threshold for the correspondence to be an inlier.
        batch_size: number of generated samples at once.
        max_iterations: maximum batches to generate. Actual number of models to try is ``batch_size * max_iterations``.
        confidence: desired confidence of the result, used for the early stopping.
        max_local_iterations: number of local optimization (polishing) iterations.
    
homographyfundamental       @   
   Gz?   )
model_typeinl_th
batch_sizemax_iter
confidencemax_lo_itersc                    s   t    || _|| _|| _|| _|| _|| _|| _|dkrVt| _	t
| _t| _d| _n6|dkrxt| _	t| _d| _t| _nt| d| j d S )Nr      r      z is unknown. Try one of )super__init__r   r   r   r   r   r   r   error_fnr   minimal_solverr   polisher_solverminimal_sample_sizer   r   NotImplementedErrorsupported_models)selfr   r   r   r   r   r   	__class__ _/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/geometry/ransac.pyr   #   s&    	
zRANSAC.__init__cpu)sample_sizepop_sizer   devicereturnc                 C   s&   t j|||d}|j|dd\}}|S )zMinimal sampler, but unlike traditional RANSAC we sample in batches to get benefit of the parallel
        processing, esp.

        on GPU
        )r*      )kdim)torchrandZtopk)r"   r(   r)   r   r*   r0   _outr%   r%   r&   sampleC   s    zRANSAC.sample)n_inlnum_tcr(   confr+   c                 C   s4   | |krdS t d| t dt | | |  S )z}Formula to update max_iter in order to stop iterations earlier
        https://en.wikipedia.org/wiki/Random_sample_consensus.g      ?)mathlogpow)r4   r5   r(   r6   r%   r%   r&   max_samples_by_confO   s    zRANSAC.max_samples_by_conf)kp1kp2r+   c              
   C   s6   |j d d \}}| ||tj|||j|jd}|S )N   dtyper*   )shaper   r/   onesr?   r*   )r"   r;   r<   r   r(   Hr%   r%   r&   estimate_model_from_minsampleW   s     z$RANSAC.estimate_model_from_minsample)r;   r<   modelsr   r+   c                 C   s   t |jdkr|d  }t |jdkr,|d  }|jd }| ||dd||dd|}||k}||jdd}| }	||	  }
||	  }||	 }|||
fS )Nr=   r   r,   r.   )	lenr@   r   expandtosumZargmaxitemclone)r"   r;   r<   rD   r   r   errorsZinlZmodels_scoreZbest_model_idxZbest_model_scoreZ
model_bestZinliers_bestr%   r%   r&   verify\   s    
"zRANSAC.verifyc                 C   s,   | j dkr$t||}|| || fS ||fS ) r   )r   r	   )r"   r;   r<   maskr%   r%   r&   remove_bad_samplesm   s    

zRANSAC.remove_bad_samples)rD   r+   c                 C   s0   t j|ddd}| jddd dk}|| S )Nr,   r=   )Zdim1Zdim2rF   r   g-C6?)r/   Zdiagonalabsmin)r"   rD   Zmain_diagonalrP   r%   r%   r&   remove_bad_modelsv   s    zRANSAC.remove_bad_models)r;   r<   inliersr+   c              
   C   sF   || d  }|| d  }| d}| ||tjd||j|jd}|S )Nr,   r>   )sizer   r/   rA   r?   r*   )r"   r;   r<   rU   Zkp1_inlZkp2_inlZnum_inlmodelr%   r%   r&   polish_model}   s    
zRANSAC.polish_modelN)r;   r<   weightsr+   c                 C   sz  t |tjstdt| t |tjs<tdt| t|jdksZtd|j t|jdksxtd|j |jd |jd kr|jd | jk rtd| j d|j d	|j t	| j}t|}tj
d
d
|j|jd}tj
|d|jtjd}t| jD ]j}| | j|| j|j}	||	 }
||	 }| |
|\}
}t|
dkrRq| |
|}| |}|du st|dkrq| |||| j\}}}||krt| jD ]r}| |||}|du st|dkrސq| |||| j\}}}||kr| d }| }|}n q$q| }| }|}t| t||| j| j}|d | j |kr qrq||fS )a  Main forward method to execute the RANSAC algorithm.

        Args:
            kp1 (torch.Tensor): source image keypoints :math:`(N, 2)`.
            kp2 (torch.Tensor): distance image keypoints :math:`(N, 2)`.
            weights (torch.Tensor): optional correspondences weights. Not used now

        Returns:
            - Estimated model, shape of :math:`(1, 3, 3)`.
            - The inlier/outlier mask, shape of :math:`(1, N)`, where N is number of input correspondences.
        z#Input kp1 is not torch.Tensor. Got z#Input kp2 is not torch.Tensor. Got r=   z&Invalid kp1 shape, we expect Nx2 Got: z&Invalid kp2 shape, we expect Nx2 Got: r   zLkp1 and kp2 should be                              equal shape at at least [z', 2],                              got z,    r>   r,   )r*   r?   N)
isinstancer/   Tensor	TypeErrortyperG   r@   
ValueErrorr   floatzerosr?   r*   boolranger   r3   r   rQ   rC   rT   rN   r   r   rX   rL   intr:   r   )r"   r;   r<   rY   Zbest_score_totalr5   Zbest_model_totalZinliers_best_totaliZidxsZkp1_sampledZkp2_sampledrD   rW   rU   Zmodel_scoreZlo_stepZmodel_lor1   Z
inliers_loZscore_loZnew_max_iterr%   r%   r&   forward   sl    $





zRANSAC.forward)r   r   r   r   r   r   )N)__name__
__module____qualname____doc__r!   strr`   rd   r   r/   r*   r\   r3   staticmethodr:   rC   r   rN   rQ   rT   rX   r   rf   __classcell__r%   r%   r#   r&   r
      sF         !
"	 )rj   r7   typingr   r   r/   Ztorch.nnnnZkornia.geometryr   r   r   r   Zkornia.geometry.homographyr   r	   __all__Moduler
   r%   r%   r%   r&   <module>   s   