
    jH                        d dl mZ d dlmZ d dlZd dlZddlmZm	Z	 g dZ
dede	fd	Zd
e	defdZdeej                 deeej                 eej                 f         fdZdee         ej        z  deej        z  fdZd2deej                 dedej        fdZd3dej        dedej        fdZdeeef         dedeeef         fdZ	 d4dej        dedeeef         dedej        f
dZdej        deeef         d eeef         dej        fd!Z	 	 d5dej        dedeeef         d#ed$eeef         dz  dej        fd%Z	 	 d6d'ej        deded(edej        f
d)Zd'ej        dej        fd*Zd+ej        defd,Zdej        deeef         dej        fd-Zd.ej        dej        deej                 fd/Zej         d&fd.ej        d+ej        d0edeej                 fd1Z!dS )7    )deepcopy)ceilN   )BoundingBox	Polygon4P)bbox_to_polygonpolygon_to_bboxresolve_enclosing_bboxresolve_enclosing_rbboxrotate_boxescompute_expanded_shaperotate_imageremove_image_paddingestimate_page_angleconvert_to_relative_coordsrotate_abs_geomsextract_cropsextract_rcropsdetach_scoresbboxreturnc                     | d         | d         d         | d         d         f| d         d         | d         d         f| d         fS )zpConvert a bounding box to a polygon

    Args:
        bbox: a bounding box

    Returns:
        a polygon
    r   r    )r   s    W/var/www/html/Carbon-Document/venv/lib/python3.11/site-packages/doctr/utils/geometry.pyr   r       sE     7T!WQZa,tAwqz471:.FQOO    polygonc                     t          |  \  }}t          |          t          |          ft          |          t          |          ffS )zsConvert a polygon to a bounding box

    Args:
        polygon: a polygon

    Returns:
        a bounding box
    )zipminmax)r   xys      r   r	   r	   ,   s>     =DAqFFCFFc!ffc!ff---r   boxesc                     dt           j        dt          t           j        t           j        f         fdt          fd| D              \  }}t	          |          t	          |          fS )a)  Detach the objectness scores from box predictions

    Args:
        boxes: list of arrays with boxes of shape (N, 5) or (N, 5, 2)

    Returns:
        a tuple of two lists: the first one contains the boxes without the objectness scores,
        the second one contains the objectness scores
    r#   r   c                     | j         dk    r| d d d df         | d d df         fS | d d d df         | d d ddf         fS )N   )ndim)r#   s    r   _detachzdetach_scores.<locals>._detachD   s^    :??CRC=%2,..QQQV}eAAAr2I...r   c              3   .   K   | ]} |          V  d S )Nr   ).0boxr)   s     r   	<genexpr>z detach_scores.<locals>.<genexpr>I   s+      !@!@3''#,,!@!@!@!@!@!@r   )npndarraytupler   list)r#   	loc_preds
obj_scoresr)   s      @r   r   r   9   st    /rz /eBJ
,B&C / / / /
  !@!@!@!@%!@!@!@AIz	??D,,,,r   bboxesc                    t          | t          j                  r|t          j        | dd          \  }}}}t          j        |                                |                                |                                |                                g          S t          d | D              \  }}t          |          t          |          ft          |          t          |          ffS )aG  Compute enclosing bbox either from:

    Args:
        bboxes: boxes in one of the following formats:

            - an array of boxes: (*, 4), where boxes have this shape:
            (xmin, ymin, xmax, ymax)

            - a list of BoundingBox

    Returns:
        a (1, 4) array (enclosing boxarray), or a BoundingBox
       r   axisc                     g | ]	}|D ]}|
S r   r   )r+   r,   points      r   
<listcomp>z*resolve_enclosing_bbox.<locals>.<listcomp>_   s%    >>>s#>>U>>>>r   )
isinstancer.   r/   splitarrayr   r    r   )r4   xminyminxmaxymaxr!   r"   s          r   r
   r
   M   s     &"*%% 2!#&!!!<!<!<dD$xTXXZZTXXZZHIII>>f>>>?1AA#a&&#a&&!111r      rbboxesintermed_sizec                     t          j        | d          }||z  }t          j        |                    t           j                            }t          j        |          |z  S )a  Compute enclosing rotated bbox either from:

    Args:
        rbboxes: boxes in one of the following formats:

            - an array of boxes: (*, 4, 2), where boxes have this shape:
            (x1, y1), (x2, y2), (x3, y3), (x4, y4)

            - a list of BoundingBox
        intermed_size: size of the intermediate image

    Returns:
        a (4, 2) array (enclosing rotated box)
    r   r7   )r.   concatenatecv2minAreaRectastypeint32	boxPoints)rD   rE   cloudrects       r   r   r   c   sT     wQ777E	]E?5<<1122D=..r           pointsanglec                 .   |t           j        z  dz  }t          j        t          j        |          t          j        |           gt          j        |          t          j        |          gg| j                  }t          j        | |j                  S )zRotate points counter-clockwise.

    Args:
        points: array of size (N, 2)
        angle: angle between -90 and +90 degrees

    Returns:
        Rotated points
         f@dtype)r.   pir>   cossinrU   matmulT)rP   rQ   	angle_radrotation_mats       r   rotate_abs_pointsr]   y   s     %I8
&

bfY///	026)3D3DbfYFWFW2XYagam  L 9V\^,,,r   	img_shapec                    t          j        | d         dz  | d         dz  g| d          dz  | d         dz  gg          }t          ||          }dt          j        |                              d          z  }|d         |d         fS )zCompute the shape of an expanded rotated image

    Args:
        img_shape: the height and width of the image
        angle: angle between -90 and +90 degrees

    Returns:
        the height and width of the rotated image
    r   r&   r   r7   )r.   r>   r]   absr    )r^   rQ   rP   rotated_pointswh_shapes        r   r   r      s     	1	9Q<!+,
A,	IaL1,-#  F
 'vu55N26.))--1-555HA;##r   Tgeomsexpandc           	         | j         dk    rJt          j        | ddddgf         | ddddgf         | ddddgf         | ddddgf         gd          n| }|                    t          j                  }|dxx         |d         dz  z  cc<   |d         dz  |d         z
  |d<   t          |                    d	d          |                              d	d
d          }|rt          ||          n|}|d         |d         dz  z                       d|d                   |d<   |d         dz  |d         z
                      d|d                   |d<   |S )a  Rotate a batch of bounding boxes or polygons by an angle around the
    image center.

    Args:
        geoms: (N, 4) or (N, 4, 2) array of ABSOLUTE coordinate boxes
        angle: anti-clockwise rotation angle in degrees
        img_shape: the height and width of the image
        expand: whether the image should be padded to avoid information loss

    Returns:
        A batch of rotated polygons (N, 4, 2)
    r&   Nr   r      r7   .r   .r   r'   r6   )	r(   r.   stackrJ   float32r]   reshaper   clip)rc   rQ   r^   rd   polysrotated_polystarget_shapes          r   r   r      s   * :?? 	%Aq6	"E!!!aV)$4eAAA1vI6FaaaRSUVQWiHXY`abbbb 

 LL$$E 
&MMMYq\A%%MMMaL1$uV}4E&M &emmB&:&:EBBJJ2qRSTTM?ET))U;;;9L*62\!_q5HHNNqR^_`RabbM&)!_q0=3HHNNqR^_`RabbM&r   r2   
orig_shape
dest_shapec                    t          |          dk    rt          dt          |                     t          |          dk    rt          dt          |                     |\  }}|\  }}|                                 }| dddddf         |z  ||z
  dz  z   |z  |dddddf<   | dddddf         |z  ||z
  dz  z   |z  |dddddf<   |S )a  Remaps a batch of rotated locpred (N, 4, 2) expressed for an origin_shape to a destination_shape.
    This does not impact the absolute shape of the boxes, but allow to calculate the new relative RotatedBbox
    coordinates after a resizing of the image.

    Args:
        loc_preds: (N, 4, 2) array of RELATIVE loc_preds
        orig_shape: shape of the origin image
        dest_shape: shape of the destination image

    Returns:
        A batch of rotated loc_preds (N, 4, 2) expressed in the destination referencial
    r&   z'Mask length should be 2, was found at: z.Image_shape length should be 2, was found at: Nr   r   )len
ValueErrorcopy)r2   rp   rq   orig_height
orig_widthdest_height
dest_widthmboxess           r   remap_boxesr{      s    :!T3z??TTUUU
:![#j//[[\\\(K(K^^F!!!!QQQ'*Z7J<SWX;XX\ffF111aaa7O!!!!QQQ'*[8[;=VZ[<[[_jjF111aaa7OMr         ?	min_anglero   c           	         |                                  }|j        dk    rJt          j        |ddddgf         |ddddgf         |ddddgf         |ddddgf         gd          }t	          |          |k     st	          |          d|z
  k    r|S |t          j        z  dz  }t          j        t          j        |          t          j        |           gt          j        |          t          j        |          gg|j	        	          }t          j        |dddddf         |d         z  |dddddf         |d         z  fd
          }|d         dz  |d         dz  f}	|	t          j
        ||	z
  |          z   }
t          j        |
dddddf         |d         z  |
dddddf         |d         z  fd
          }|t          |||          }|S )a  Rotate a batch of straight bounding boxes (xmin, ymin, xmax, ymax, c) or rotated bounding boxes
    (4, 2) of an angle, if angle > min_angle, around the center of the page.
    If target_shape is specified, the boxes are remapped to the target shape after the rotation. This
    is done to remove the padding that is created by rotate_page(expand=True)

    Args:
        loc_preds: (N, 4) or (N, 4, 2) array of RELATIVE boxes
        angle: angle between -90 and +90 degrees
        orig_shape: shape of the origin image
        min_angle: minimum angle to rotate boxes
        target_shape: shape of the destination image

    Returns:
        A batch of rotated boxes (N, 4, 2): or a batch of straight bounding boxes
    r&   Nr   r   rf   r7   Z   rS   rT   r'   )rp   rq   )ru   r(   r.   ri   r`   rV   r>   rW   rX   rU   rY   r{   )r2   rQ   rp   r}   ro   _boxesr[   r\   rP   image_centerra   rotated_boxess               r   r   r      s/   . ^^F{aqqq1a&y!qqq1a&y!qqq1a&y!qqq1a&y!	 
 
 
 5zzIUb9n!<!<%I8
&

bfY///	026)3D3DbfYFWFW2XYagam  L 6!!!QQQ'?Z]#BF111aaaQR7OV`abVcDc"dkmnnnFqMA%z!}q'89L!BIf|.C\$R$RRN "	111a	 :a=	0.AAAq2IJWXM2YZac! ! !M
 #MjUabbbr   Fimagepreserve_origin_shapec                    |rt          | j        dd         |          }t          t          dt	          |d         | j        d         z
                                t          t          dt	          |d         | j        d         z
                                }}t          j        | |dz  ||dz  z
  f|dz  ||dz  z
  fdf          }n| }|j        dd         \  }}	t          j        |	dz  |dz  f|d          }
t          j	        ||
|	|f          }|rd| j        d         | j        d         z  |j        d         |j        d         z  k    r|j        d         |j        d         z  | j        d         | j        d         z  k    rGdt          |j        d         | j        d         z  | j        d         z  |j        d         z
            }}nFt          |j        d         | j        d         z  | j        d         z  |j        d         z
            d}}t          j        ||dz  ||dz  z
  f|dz  ||dz  z
  fdf          }|r7t          j
        || j        dd         ddd         t          j                  }|S )	a  Rotate an image counterclockwise by an given angle.

    Args:
        image: numpy tensor to rotate
        angle: rotation angle in degrees, between -90 and +90
        expand: whether the image should be padded before the rotation
        preserve_origin_shape: if expand is set to True, resizes the final output to the original image size

    Returns:
        Rotated array, padded by 0 by default.
    Nr&   r   r   )r   r   r|   r'   )interpolation)r   shapeintr    r   r.   padrH   getRotationMatrix2D
warpAffineresizeINTER_LINEAR)r   rQ   rd   r   	exp_shapeh_padw_padexp_imgheightwidthrot_matrot_imgs               r   r   r     s   &  *5;rr?EBB	AtIaL5;q>9::;;<<AtIaL5;q>9::;;<<  &%1*eeqj.@!AEQJPUX]abXbPbCcek lmmM"1"%MFE%uqy&1*&=ucJJGnWgv??G bKNU[^+q1AGMRSDT1TUUa 7=#33AUV8WXX #gmA&6Q&G%+VW.&X[b[hij[k&k"l"lu  #7=#3ek!n#Du{ST~#UX_XefgXh#hiiklufW
EEQJ4F'G%ST*V[^cgh^hVhIikq&rssG  	bj%+crc*:44R4*@PSP`aaaGNr   c                    t          j        | d          }t          j        | d          }t          j        |          d         ddg         \  }}t          j        |          d         ddg         \  }}| ||dz   ||dz   f         S )zRemove black border padding from an image

    Args:
        image: numpy tensor to remove padding from

    Returns:
        Image with padding removed
    r   r7   r   r'   )r.   anywhere)r   rowscolsrminrmaxcmincmaxs          r   r   r   L  s     6%a   D6%a   D$"Ar7+JD$$"Ar7+JD$q$/122r   rm   c           
         | ddddf         | ddddf         z   }| ddddf         | ddddf         z   }| ddddf         | ddddf         z   }| ddddf         | ddddf         z   }t          j        dd          5  	 t          t          j        t          j        ||z
  ||z
  z            dz  t           j        z                      cddd           S # t          $ r Y ddd           d	S w xY w# 1 swxY w Y   dS )
zTakes a batch of rotated previously ORIENTED polys (N, 4, 2) (rectified by the classifier) and return the
    estimated angle ccw in degrees
    Nr   rf   r   r&   raise)divideinvalid   rO   )r.   errstatefloatmedianarctanrV   FloatingPointError)rm   xleftyleftxrightyrights        r   r   r   ^  s   
 !!!Q'NU111a7^+E!!!Q'NU111a7^+E111a7^eAAAq!Gn,F111a7^eAAAq!Gn,F	GW	5	5	5  		")UV^$GHH3NQSQVVWW        
 " 	 	 	       
	         s1   C9AC
C6'C95C66C99C= C=c                 h   | j         dk    rv| j        dd         dk    rct          j        | j        t          j                  }| d         |d         z  |d<   | d         |d         z  |d<   |                    dd          S | j         d	k    r| j        d         d
k    rt          j        | j        t          j                  }| ddddd	f         |d         z  |ddddd	f<   | ddddd	f         |d         z  |ddddd	f<   |                    dd          S t          d| j                   )zConvert a geometry to relative coordinates

    Args:
        geoms: a set of polygons of shape (N, 4, 2) or of straight boxes of shape (N, 4)
        img_shape: the height and width of the image

    Returns:
        the updated geometry
    rf   r   Nr6   r&   rT   rg   rh   r   r&   r6   z invalid format for arg `geoms`: )r(   r   r.   emptyrj   rl   rt   )rc   r^   polygonsr#   s       r   r   r   p  sA    zQ5;qrr?f44!x2:FFF =9Q<7 =9Q<7}}Q"""zQ5;q>Q..HU[
CCCaaa1f	!4aaa1fqqq!$Q$w)A,6aaaAgzz!Q
EEE
F
FFr   imgc                     |j         d         dk    rg S |j         d         dk    rt          d          |                                } j         dd         \  }}t          j        |j        t          j                  sj|ddddgfxx         |z  cc<   |ddddgfxx         |z  cc<   |                                                    t                    }|ddxx         dz  cc<   t           fd|D                       S )	a  Created cropped images from list of bounding boxes

    Args:
        img: input image
        boxes: bounding boxes of shape (N, 4) where N is the number of boxes, and the relative
            coordinates (xmin, ymin, xmax, ymax)

    Returns:
        list of cropped images
    r   r   r6   zGboxes are expected to be relative and in order (xmin, ymin, xmax, ymax)Nr&   rf   c                 \    g | ](}|d          |d         |d         |d         f         )S )r   rf   r   r&   r   )r+   r,   r   s     r   r;   z!extract_crops.<locals>.<listcomp>  s;    MMMsSQ#a&#a&3q6/9:MMMr   )r   AssertionErrorru   r.   
issubdtyperU   integerroundrJ   r   r   )r   r#   r   hws   `    r   r   r     s    {1~	{1~fggg ZZ\\F9RaR=DAq=rz22 qqq1a&yQqqq1a&yQ&&s++qrr


a


MMMMfMMMNNNr   assume_horizontalc           	         |j         d         dk    rg S |j         dd         dk    rt          d          |                                }| j         dd         \  }}t          j        |j        t          j                  s.|dddddfxx         |z  cc<   |dddddfxx         |z  cc<   | |r'g }|D ]}t          j        |d          }	||dddf         |	d         k              }
||dddf         |	d         k             }|
t          j        |
dddf                            }
|
d         }|
d         }|t          j        |dddf                            }|d         }|d         }t          j	        ||||g|	          }t          j
                            ||z
            }t          j
                            ||z
            }t          j
                            ||z
            }t          j
                            ||z
            }t          t          |          t          |                    }t          t          |          t          |                    }t          j	        ddgd|dz
  g|dz
  dg|dz
  |dz
  gg|	          t          j        |          }t          j        |||f          }|                    |           !n|dddd
f                             t          j                  t          j
                            dddf         dddf         z
  d          t          j
                            dddf         dddf         z
  d          t          j        |j         d         d
df|	          dz
  xddddf<   ddddf<   dz
  ddddf<   fdt+          |j         d                   D             }|S )aM  Created cropped images from list of rotated bounding boxes

    Args:
        img: input image
        polys: bounding boxes of shape (N, 4, 2)
        dtype: target data type of bounding boxes
        assume_horizontal: whether the boxes are assumed to be only horizontally oriented

    Returns:
        list of cropped images
    r   r   Nr   z:polys are expected to be quadrilateral, of shape (N, 4, 2)r&   r7   r'   rT   rf   c                     g | ]_}t          j        t          j        |         |                   t          |                   t          |                   f          `S r   )rH   r   getAffineTransformr   )r+   idxd1d2dst_ptssrc_imgsrc_ptss     r   r;   z"extract_rcrops.<locals>.<listcomp>
  sn     
 
 
  N&ws|WS\BBRWs2c7||,	 
 
 
r   )r   r   ru   r.   r   rU   r   meanargsortr>   linalgnormr    r   rH   getPerspectiveTransformwarpPerspectiveappendrJ   rj   zerosrange)r   rm   rU   r   r   r   r   cropsr,   centroidleft_pointsright_pointstop_left_ptbottom_left_pttop_right_ptbottom_right_pt
box_pointswidth_upperwidth_lowerheight_leftheight_right
rect_widthrect_height
affine_matcropr   r   r   r   r   s                            @@@@@r   r   r     sW    {1~	{122&  YZZZ ZZ\\FIbqbMMFE=rz22 "qqq!!!Qw5 qqq!!!Qw6!G  O
 7	 7	Cws+++H c!!!Q$i(1+56Ks111a4yHQK78L &bjQQQT1B&C&CDK%a.K(_N'
<13E(F(FGL'?L*2.OnlOL  J )..)CDDK)..>)IJJK)..+)EFFK9>>/L*HIIL S--s;/?/?@@Jc+..L0A0ABBKhFa(!^Q'!^[1_5   G 4ZIIJ &[) D LLo7	v BQB-&&rz22Y^^GAAAqDMGAAAqDM9^CCY^^GAAAqDMGAAAqDM9^CC(FLOQ2%@@@.01f41a7111a7+61a
 
 
 
 
 
 
 
 V\!_--
 
 
 Lr   )rC   )rO   )T)r|   N)FF)"ru   r   mathr   rH   numpyr.   common_typesr   r   __all__r   r	   r1   r/   r0   r   r
   r   r   r   r]   r   boolr   r{   r   r   r   r   r   r   rj   r   r   r   r   <module>r      sa               



     0 0 0 0 0 0 0 0  $	P+ 	P) 	P 	P 	P 	P
.Y 
.; 
. 
. 
. 
.-bj) -eD4Dd2:FV4V.W - - - -(24#4rz#A 2kTVT^F^ 2 2 2 2,/ /T"*%5 /c /UWU_ / / / /,- -bj - - - - - -"$eCHo $e $cSVh $ $ $ $2 	& &:&& S#X& 	&
 Z& & & &R2: 5c? PUVY[^V^P_ dfdn    < +/6 6z66 c3h6 	6
 S/D(6 Z6 6 6 6x "'	. .:.. .  	.
 Z. . . .b3
 3rz 3 3 3 3$rz e    $Gbj GU38_ GQSQ[ G G G G2Orz O"* Obj9I O O O O< /1jTYm m	mJmMQm	"*m m m m m mr   