o
    'jg                     @   sN   d Z ddlZddlZddlmZ ddlmZ ddlZdd Z	G dd dZ
dS )	z
This code is refer from:
https://github.com/open-mmlab/mmocr/blob/main/mmocr/datasets/pipelines/textdet_targets/fcenet_targets.py
    N)fftnormc                 C   s(   t | dksJ t| d | d d  S )N      r   :0yE>)lenabs)Zvec r
   g/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/paddleocr/ppocr/data/imaug/fce_targets.pyvector_slope   s   r   c                       s   e Zd ZdZ						d. fdd		Zd
d Zdd Zdd Zdd Zdd Z	dd Z
d/ddZdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%efd&d'Zd(d) Zd*d+ Zd,d- Z  ZS )0FCENetTargetsa  Generate the ground truth targets of FCENet: Fourier Contour Embedding
    for Arbitrary-Shaped Text Detection.

    [https://arxiv.org/abs/2104.10442]

    Args:
        fourier_degree (int): The maximum Fourier transform degree k.
        resample_step (float): The step size for resampling the text center
            line (TCL). It's better not to exceed half of the minimum width.
        center_region_shrink_ratio (float): The shrink ratio of text center
            region.
        level_size_divisors (tuple(int)): The downsample ratio on each level.
        level_proportion_range (tuple(tuple(int))): The range of text sizes
            assigned to each level.
             @333333?          )r   g      ?)g?g?)g?      ?       @c                    sb   t    t|tsJ t|tsJ t|t|ksJ || _|| _|| _|| _|| _	|| _
d S N)super__init__
isinstancetupler   fourier_degreeresample_stepcenter_region_shrink_ratiolevel_size_divisorslevel_proportion_rangeorientation_thr)selfr   r   r   r    r!   r"   kwargs	__class__r
   r   r   0   s   
	
zFCENetTargets.__init__c                 C   s   |j dkr|t|ddd d }n
|t|ddd  }|j dkr0|t|ddd d }n
|t|ddd  }tttj|| ddddS )Nr   Zaxisr   r'   r   g      r   )ndimr   reshapenpZarccosZclipsum)r#   Zvec1Zvec2Z	unit_vec1Z	unit_vec2r
   r
   r   vector_angleE   s   

zFCENetTargets.vector_anglec                    sn   j dksJ  jd dksJ  jd dksJ t|ts J |dks&J  fddtt d D }t|}tdg| }|t	|d  }d} d g}td|D ]S}	|	| }
|d t|k r|
||d  kr|d7 }|d t|k r|
||d  ksk|
||  }|t|kr n|||  } |  |d   |  |  }|
| qU|
 d  t|}|S )	a   Resample n points on a line.

        Args:
            line (ndarray): The points composing a line.
            n (int): The resampled points number.

        Returns:
            resampled_line (ndarray): The points composing the resampled line.
        r   r   r   c                    $   g | ]}t  |d    |  qS r   r   .0iliner
   r   
<listcomp>c   s    z/FCENetTargets.resample_line.<locals>.<listcomp>g        r   r'   )r*   shaper   intranger   r-   r,   Zcumsumfloatappendarray)r#   r5   nZlength_listtotal_lengthZlength_cumsumZdelta_lengthZcurrent_edge_indZresampled_liner3   Zcurrent_line_lenZcurrent_edge_end_shiftZend_shift_ratioZcurrent_pointr
   r4   r   resample_lineR   sZ   


zFCENetTargets.resample_linec                 C   s   |j dksJ |jd dksJ |jd dksJ | || j\}}|| || }}t||g}|d dk r>t||d< ||d |d  }||d |d t|  }tj|ddtj|dd }	|	d dkrp||}
}n||}
}|||
|fS )a  Get the respective points composing head edge, tail edge, top
        sideline and bottom sideline.

        Args:
            points (ndarray): The points composing a text polygon.

        Returns:
            head_edge (ndarray): The two points composing the head edge of text
                polygon.
            tail_edge (ndarray): The two points composing the tail edge of text
                polygon.
            top_sideline (ndarray): The points composing top curved sideline of
                text polygon.
            bot_sideline (ndarray): The points composing bottom curved sideline
                of text polygon.
        r   r      r   r(   )r*   r7   find_head_tailr"   r,   vstackr   mean)r#   points	head_inds	tail_indsZ	head_edgeZ	tail_edge
pad_points	sideline1	sideline2Zsideline_mean_shiftZtop_sidelineZbot_sideliner
   r
   r   reorder_poly_edge   s*   
zFCENetTargets.reorder_poly_edgec           "         s  |j dksJ |jd dksJ |jd dksJ t|ts J t|dkrt||d g}|dd |dd   g }g }t D ]4\}} fdd|d |d fD } | }	t| 	||	}
| 	|	d |	d }|
|
 |
| qDt|tj }t|tj }tj|dd	}tt|dd | dd	t|dd | dd	}|t| }tt }d
| d|  }|d| 7 }t|d dkr|t|d d   d7  < |d  d7  < |d| 7 }t||g}tt|t|d f}tt|d tt|d  }dtdtj d
  tt|d
 d
 d d  }|t| }tt|D ]}|| ||d |t| d  | d  ||ddf< q8t| |j\}}|| d t| }|d t| }|d t| }||kr||}}||}}||g}||g}||fS t|d |d  t|d |d   t|d |d  t|d |d   k rddgddgg}ddgddgg}nddgddgg}ddgddgg}t||d d  ||d d   t||d d  ||d d    } t||d d  ||d d   t||d d  ||d d    }!| |!| kr=|d }|d }||fS |d }|d }||fS )a  Find the head edge and tail edge of a text polygon.

        Args:
            points (ndarray): The points composing a text polygon.
            orientation_thr (float): The threshold for distinguishing between
                head edge and tail edge among the horizontal and vertical edges
                of a quadrangle.

        Returns:
            head_inds (list): The indexes of two points composing head edge.
            tail_inds (list): The indexes of two points composing tail edge.
        r   r   r@   r   Nr'   c                    s   g | ]}|t   qS r
   )r   )r2   xZedge_vecr
   r   r6      s    z0FCENetTargets.find_head_tail.<locals>.<listcomp>r(         ?g333333?gffffff?g?   r   r   r   )r*   r7   r   r:   r   r,   rB   	enumerater-   r.   r;   r<   pirC   maximumr   maxzerosconcatenateZarangesqrtexppowerr9   Zunravel_indexZargmaxr   )"r#   rD   r"   rG   Z	theta_sumZadjacent_vec_thetar3   Z	edge_vec1Zadjacent_indZadjacent_edge_vecZtemp_theta_sumZtemp_adjacent_thetaZtheta_sum_scoreZadjacent_theta_scoreZpoly_centerZ	edge_distZ
dist_scoreZposition_scoreZscoreZ	pad_scoreZscore_matrixrK   ZgaussianZ
head_startZtail_incrementZ
tail_startZhead_endZtail_endrE   rF   Zhorizontal_edge_indsZvertical_edge_indsZvertical_len_sumZhorizontal_len_sumr
   rL   r   rA      s   


"








zFCENetTargets.find_head_tailc           
         s    j j   krdksJ  J  jd jd   kr!dks$J  J  jd dks-J jd dks6J t|ts=J t fddtt d D }tfddttd D }|| d }ttt|| d}| 	 |}| 	|}	||	fS )a  Resample two sidelines to be of the same points number according to
        step size.

        Args:
            sideline1 (ndarray): The points composing a sideline of a text
                polygon.
            sideline2 (ndarray): The points composing another sideline of a
                text polygon.
            resample_step (float): The resampled step size.

        Returns:
            resampled_line1 (ndarray): The resampled line 1.
            resampled_line2 (ndarray): The resampled line 2.
        r   r   r   c                    r/   r0   r   r1   )rH   r
   r   r6   &      z4FCENetTargets.resample_sidelines.<locals>.<listcomp>c                    r/   r0   r   r1   )rI   r
   r   r6   *  rX   )
r*   r7   r   r:   r-   r9   r   rR   r8   r?   )
r#   rH   rI   r   Zlength1Zlength2r>   Zresample_point_numZresampled_line1Zresampled_line2r
   )rH   rI   r   resample_sidelines  s     (z FCENetTargets.resample_sidelinesc                 C   s  t |tsJ |\}}t||ftj}g }|D ]}|dd}| |\}	}	}
}| |
|| j\}}|ddd }t	|t	|krCq|| d }t
|d |d  d }t
|d |d  d }t|| j }t|| j }t	||| d kr||t	||  }||t	||  }||t	||  }tdt	|d D ]\}|| || ||  | j  }||d  ||d  ||d   | j  }||d  ||d  ||d   | j  }|| || ||  | j  }t||||gtj}|| qqt||d |S )a  Generate text center region mask.

        Args:
            img_size (tuple): The image size of (height, width).
            text_polys (list[list[ndarray]]): The list of text polygons.

        Returns:
            center_region_mask (ndarray): The text center region mask.
        r'   r   Nr   r   r   )r   r   r,   rS   uint8r+   rJ   rY   r   r   r   r8   r9   r   rB   astypeint32r;   cv2fillPoly)r#   img_size
text_polyshwZcenter_region_maskZcenter_region_boxespolyZpolygon_points_Ztop_lineZbot_lineZresampled_top_lineZresampled_bot_lineZcenter_lineZline_head_shrink_lenZline_tail_shrink_lenZhead_shrink_numZtail_shrink_numr3   tltrbrblZcurrent_center_boxr
   r
   r   generate_center_region_mask7  s   



z)FCENetTargets.generate_center_region_mask  c                 C   s0  g }t t|D ]2}|| }|t|d kr|d }n||d  }||d |d  d |d |d  d  d  qt|}t||d  | }|tj}g }	t t|D ]:}|| }
|| }|t|d kro|d }n||d  }|
dkrzqX|| |
 }t |
D ]}|||  }|	| qqXt|	S )a  Resample one polygon with n points on its boundary.

        Args:
            polygon (list[float]): The input polygon.
            n (int): The number of resampled points.
        Returns:
            resampled_polygon (list[float]): The resampled polygon.
        r   r   r   rM   r   )r9   r   r;   r-   r,   r<   r[   r\   )r#   polygonr=   lengthr3   p1Zp2r>   Zn_on_each_linenew_polygonnumZdxdyjpointr
   r
   r   resample_polygonu  s2   	
4

zFCENetTargets.resample_polygonc           	      C   s   ||j dd }t|dddf }|dddf }t|}t||dd  }|| }t||d |d| g}|S )zNormalize one polygon so that its start point is at right most.

        Args:
            polygon (list[float]): The origin polygon.
        Returns:
            new_polygon (lost[float]): The polygon with start point at right.
        r   r(   Nr   r   )rC   r,   r	   ZargsortZargminrT   )	r#   rk   Ztemp_polygonrK   yZindex_xZindex_yindexrn   r
   r
   r   normalize_polygon  s   
zFCENetTargets.normalize_polygonc                 C   s\   |dddf |dddf d  }t |t| }t|| d |d|d  f}|S )a*  Perform Fourier transformation to generate Fourier coefficients ck
        from polygon.

        Args:
            polygon (ndarray): An input polygon.
            fourier_degree (int): The maximum Fourier degree K.
        Returns:
            c (ndarray(complex)): Fourier coefficients.
        Nr   r   y              ?)r   r   r,   hstack)r#   rk   r   rD   Zc_fftcr
   r
   r   poly2fourier  s   $
$zFCENetTargets.poly2fourierc                 C   s   t ||d  t ||d  kr|S t ||d  t ||d  k r-|ddd S t ||d  t ||d  krA|S |ddd S )a  Make sure the polygon reconstructed from Fourier coefficients c in
        the clockwise direction.

        Args:
            polygon (list[float]): The origin polygon.
        Returns:
            new_polygon (lost[float]): The polygon in clockwise point order.
        r   Nr'   r   )r,   r	   )r#   rw   r   r
   r
   r   	clockwise  s   $	$$zFCENetTargets.clockwisec                 C   s^   |  |}| |}| ||}| ||}t|d}t|d}t||g}|S )ag  Calculate Fourier signature from input polygon.

        Args:
              polygon (ndarray): The input polygon.
              fourier_degree (int): The maximum Fourier degree K.
        Returns:
              fourier_signature (ndarray): An array shaped (2k+1, 2) containing
                  real part and image part of 2k+1 Fourier coefficients.
        r)   )	rr   ru   rx   ry   r,   realr+   imagrv   )r#   rk   r   Zresampled_polygonfourier_coeffZ	real_partZ
image_partZfourier_signaturer
   r
   r   cal_fourier_signature  s   


z#FCENetTargets.cal_fourier_signaturec              	   C   s  t |tsJ |\}}| j}tj|d d ||ftjd}tj|d d ||ftjd}|D ]}tj||ftjd}	t|d}
t	
|	|
tjd | |
d |}t| |d D ]}|dkr|	||| df  d|	 ||| ddddf   ||| ddddf< |	||| df  d|	 ||| ddddf   ||| ddddf< q]t|	dk}tjt|tjd| }|dddf |dddf }}||df | ||||f< ||df | ||||f< q]q.||fS )a  Generate Fourier coefficient maps.

        Args:
            img_size (tuple): The image size of (height, width).
            text_polys (list[list[ndarray]]): The list of text polygons.

        Returns:
            fourier_real_map (ndarray): The Fourier coefficient real part maps.
            fourier_image_map (ndarray): The Fourier coefficient image part
                maps.
        r   r   Zdtyper   r'   r   r   NrM   )r   r   r   r,   rS   Zfloat32rZ   r<   r+   r]   r^   r[   r\   r}   r9   Zargwhereonesr   Zint64)r#   r_   r`   ra   rb   kZreal_mapZimag_maprc   maskrk   r|   r3   ZyxZk_indrs   rK   r
   r
   r   generate_fourier_maps  s2   "z#FCENetTargets.generate_fourier_mapsc                 C   s\   t |tsJ |\}}tj||ftjd}|D ]}tj|tjdd}t	||d q|S )a,  Generate text center region mask and geometry attribute maps.

        Args:
            img_size (tuple): The image size (height, width).
            text_polys (list[list[ndarray]]): The list of text polygons.

        Returns:
            text_region_mask (ndarray): The text region mask.
        r~   r   r   )
r   r   r,   rS   rZ   r<   r\   r+   r]   r^   )r#   r_   r`   ra   rb   Ztext_region_maskrc   rk   r
   r
   r   generate_text_region_mask  s   z'FCENetTargets.generate_text_region_mask	mask_sizec                 C   sJ   t j|t jd}|D ]}|ddt jddd}t||d q
|S )a_  Generate effective mask by setting the ineffective regions to 0 and
        effective regions to 1.

        Args:
            mask_size (tuple): The mask size.
            polygons_ignore (list[[ndarray]]: The list of ignored text
                polygons.

        Returns:
            mask (ndarray): The effective mask of (height, width).
        r~   r'   r   r   r   )r,   r   rZ   r+   r[   r\   r]   r^   )r#   r   Zpolygons_ignorer   rc   instancer
   r
   r   generate_effective_mask&  s
   z%FCENetTargets.generate_effective_maskc                 C   s  |\}}| j }| j}dd tt|D }dd tt|D }	g }
|D ]C}tj|tjdd}t	|\}}}}t
|||d  }t|D ]\}}|d |  k rY|d k rfn qG|| |||   qGq$|D ]C}tj|tjdd}t	|\}}}}t
|||d  }t|D ]\}}|d |  k r|d k rn q|	| |||   qqjt|D ]W\}}g }|| || f}| ||| d	 }|| | ||| d	 }|| | ||	| d	 }|| | ||| \}}|| || |
t| q|
S )
av  Generate ground truth target on each level.

        Args:
            img_size (list[int]): Shape of input image.
            text_polys (list[list[ndarray]]): A list of ground truth polygons.
            ignore_polys (list[list[ndarray]]): A list of ignored polygons.
        Returns:
            level_maps (list(ndarray)): A list of ground target on each level.
        c                 S      g | ]}g qS r
   r
   r1   r
   r
   r   r6   H      z8FCENetTargets.generate_level_targets.<locals>.<listcomp>c                 S   r   r
   r
   r1   r
   r
   r   r6   I  r   r~   r   r   r   r   N)r    r!   r9   r   r,   r<   r\   r+   r]   ZboundingRectrR   rO   r;   r   ri   r   r   rT   )r#   r_   r`   Zignore_polysra   rb   Zlv_size_divsZlv_proportion_rangeZlv_text_polysZlv_ignore_polys
level_mapsrc   rk   rd   Zbox_wZbox_hZ
proportionindZproportion_rangeZignore_polyZsize_divisorZcurrent_level_mapsZlevel_img_sizeZtext_regionZcenter_regionZeffective_maskZfourier_real_mapZfourier_image_mapsr
   r
   r   generate_level_targets;  sh   
  




z$FCENetTargets.generate_level_targetsc                 C   s   t |tsJ |d }|d }|d }|j\}}}g }g }	t||D ]\}
}|
du r0|	| q"|| q"| ||f||	}|d |d |d d}| D ]\}}|||< qO|S )	zGenerate the ground truth targets for FCENet.

        Args:
            results (dict): The input result dictionary.

        Returns:
            results (dict): The output result dictionary.
        imageZpolysignore_tagsTr   r   r   )Zp3_mapsZp4_mapsZp5_maps)r   dictr7   zipr;   r   items)r#   resultsr   Zpolygonsr   ra   rb   rd   Zpolygon_masksZpolygon_masks_ignoretagrk   r   mappingkeyvaluer
   r
   r   generate_targetsv  s*   

zFCENetTargets.generate_targetsc                 C   s   |  |}|S r   )r   )r#   r   r
   r
   r   __call__  s   
zFCENetTargets.__call__)r   r   r   r   r   r   )rj   )__name__
__module____qualname____doc__r   r.   r?   rJ   rA   rY   ri   rr   ru   rx   ry   r}   r   r   r   r   r   r   r   __classcell__r
   r
   r%   r   r      s4    3)b'
>*(;%r   )r   r]   numpyr,   Z	numpy.fftr   Znumpy.linalgr   sysr   r   r
   r
   r
   r   <module>   s   