
    Ngw                        d dl mZmZmZmZmZmZmZ d dlmZ d dl	m	Z	 d dl
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 d	d
lmZmZ d	dlmZmZm Z m!Z!m"Z" d	dl#m$Z$m%Z% d Z&ddddZ'd Z(e' G d de                      Z)e' G d de                      Z*e' G d de                      Z+e)e*e+gZ,d e,D             Z-d  e.e,          D             Z/ e'e           G d de                      Z0dS )    )ListUnionDictr   AnyOptionalTuple)Iterable)copy)
getmembers
isfunctionN)Image)getPerspectiveTransform)warpPerspective   )BaseCoordElementBaseLayoutElement)cvt_coordinates_to_pointscvt_points_to_coordinatesperspective_transformationvertice_in_polygonpolygon_area)NotSupportedShapeErrorInvalidShapeErrorc                 F     t          j                    fd            }|S )Nc                 z     | g|R i |}t          |t                    rt          |           } || _        | S d S N)
isinstancer   r
   block)selfargskwargsoutfuncs       a/var/www/html/ai-engine/env/lib/python3.11/site-packages/layoutparser/elements/layout_elements.pywrapz"mixin_textblock_meta.<locals>.wrap(   sV    d4)$)))&))c+,, 	::DDJK	 	    	functoolswrapsr#   r%   s   ` r$   mixin_textblock_metar+   '   s8    _T     Kr&   
base_classc                d   | t          j        t          |          S t          | t                    D ]|\  }}|j        r|d k    r?| j        dd          D ].}t          ||          rt          ||          j        |_         n/Rt          ||          rt          ||          j        |_        }| S )Nr,   r   )	r(   partialinherit_docstringsr   r   __doc____mro__hasattrgetattr)clsr-   namer#   parents        r$   r0   r0   3   s     { !3
KKKK j11 
A 
A
d< 	+abb/  64(( #*64#8#8#@DLE z4(( A&z488@Jr&   c                 F     t          j                    fd            }|S )Nc                 Z    t          |t                    r|j        } | |g|R i |}|S r   )r   	TextBlockr   )r   otherr    r!   r"   r#   s        r$   r%   zsupport_textblock.<locals>.wrapI   sB    eY'' 	 KEd4000000
r&   r'   r*   s   ` r$   support_textblockr<   H   s8    _T     Kr&   c                   b   e Zd ZdZdZg dZddZed             Zed             Z	ed             Z
ed	             Zed
             Zed             Zd Zed             Zed             Zei dfd            Zeddedefd            Zeddedefd            ZddZd Zd Zd Zd Zd ZdS ) Intervala  
    This class describes the coordinate system of an interval, a block defined by a pair of start and end point
    on the designated axis and same length as the base canvas on the other axis.

    Args:
        start (:obj:`numeric`):
            The coordinate of the start point on the designated axis.
        end (:obj:`numeric`):
            The end coordinate on the same axis as start.
        axis (:obj:`str`):
            The designated axis that the end points belong to.
        canvas_height (:obj:`numeric`, `optional`, defaults to 0):
            The height of the canvas that the interval is on.
        canvas_width (:obj:`numeric`, `optional`, defaults to 0):
            The width of the canvas that the interval is on.
    intervalstartendaxiscanvas_heightcanvas_widthNc                     ||k    s
J d            || _         || _        |dv sJ d| d            || _        |pd| _        |pd| _        d S )Nz3Invalid input for start and end. Start must <= end.)xyzInvalid axis z. Axis must be in 'x' or 'y'r   r@   )r   rA   rB   rC   rD   rE   s         r$   __init__zInterval.__init__i   sp    |||S|||
z!!!#U4#U#U#U!!!	*/a(-Ar&   c                 D    | j         dk    r| j        S | j        | j        z
  S )a-  
        Calculate the height of the interval. If the interval is along the x-axis, the height will be the
        height of the canvas, otherwise, it will be the difference between the start and end point.

        Returns:
            :obj:`numeric`: Output the numeric value of the height.
        rG   )rC   rD   rB   rA   r   s    r$   heightzInterval.heightu   s)     9%%8dj((r&   c                 D    | j         dk    r| j        S | j        | j        z
  S )a)  
        Calculate the width of the interval. If the interval is along the y-axis, the width will be the
        width of the canvas, otherwise, it will be the difference between the start and end point.

        Returns:
            :obj:`numeric`: Output the numeric value of the width.
        rH   )rC   rE   rB   rA   rK   s    r$   widthzInterval.width   s)     9$$8dj((r&   c                 r    | j         dk    r| j        d| j        | j        f}nd| j        | j        | j        f}|S )a6  
        This method considers an interval as a rectangle and calculates the coordinates of the upper left
        and lower right corners to define the interval.

        Returns:
            :obj:`Tuple(numeric)`:
                Output the numeric values of the coordinates in a Tuple of size four.
        rG   r   )rC   rA   rB   rD   rE   )r   coordss     r$   coordinateszInterval.coordinates   sB     9j!TXt/ABFFT%6AFr&   c                 *    t          | j                  S )z
        Return the coordinates of all four corners of the interval in a clockwise fashion
        starting from the upper left.

        Returns:
            :obj:`Numpy array`: A Numpy array of shape 4x2 containing the coordinates.
        r   rQ   rK   s    r$   pointszInterval.points        ))9:::r&   c                 &    | j         | j        z   dz  S )z
        Calculate the mid-point between the start and end point.

        Returns:
            :obj:`Tuple(numeric)`: Returns of coordinate of the center.
               @rA   rB   rK   s    r$   centerzInterval.center   s     
TX%,,r&   c                      | j         | j        z  S )a.  Return the area of the covered region of the interval.
        The area is bounded to the canvas. If the interval is put
        on a canvas, the area equals to interval width * canvas height
        (axis='x') or interval height * canvas width (axis='y').
        Otherwise, the area is zero.
        )rL   rN   rK   s    r$   areazInterval.area   s     {TZ''r&   c                 *   t          |t          j                  r|j        dd         \  }}nPt          |t                    r|j        |j        }}n,t          |t          j                  r|j        \  }}nt          | 
                    ||          S )a  
        Set the height and the width of the canvas that the interval is on.

        Args:
            canvas (:obj:`Numpy array` or :obj:`BaseCoordElement` or :obj:`PIL.Image.Image`):
                The base element that the interval is on. The numpy array should be the
                format of `[height, width]`.

        Returns:
            :obj:`Interval`:
                A copy of the current Interval with its canvas height and width set to
                those of the input canvas.
        N   )rD   rE   )r   npndarrayshaper   rL   rN   r   sizeNotImplementedErrorset)r   canvashws       r$   put_on_canvaszInterval.put_on_canvas   s     fbj)) 	&<#DAqq 011 	&=&,qAA,, 	&;DAqq%%xxaax888r&   c                 <   t          |t                    rR|j        | j        k    r3|j        }|                     | j        |z   | j        |z   | j                  S t          |           S t          |t                    r:|                     |          	                                
                    |          S t          |t                    r:|                     |                                          
                    |          S t          d|j         d          NInvalid input type 
 for other)r   r>   rC   rA   	__class__rB   r
   	Rectanglerg   to_rectanglecondition_onQuadrilateralto_quadrilateral	Exceptionr   r;   ds      r$   ro   zInterval.condition_on   s     eX&& 	OzTY&&K~~dj1ndhlDINNNDzz!y)) 		O%%e,,99;;HHOOO}-- 	O%%e,,==??LLUSSS M%/MMMNNNr&   c                 <   t          |t                    rR|j        | j        k    r3|j        }|                     | j        |z
  | j        |z
  | j                  S t          |           S t          |t                    r:|                     |          	                                
                    |          S t          |t                    r:|                     |                                          
                    |          S t          d|j         d          ri   )r   r>   rC   rA   rl   rB   r
   rm   rg   rn   relative_torp   rq   rr   rs   s      r$   rv   zInterval.relative_to   s     eX&& 	OzTY&&K~~dj1ndhlDINNNDzz!y)) 		O%%e,,99;;GGNNN}-- 	O%%e,,==??KKERRR M%/MMMNNNr&   Fc                     |j         di |}t          |t                    r^| j        |j        k    rdS |s+|j        | j        cxk    o| j        cxk    o
|j        k    nc S |j        | j        cxk    o
|j        k    nc S t          |t                    st          |t                    r|j	        \  }}}}|r5| j        dk    r|| j        cxk    o|k    nc S || j        cxk    o|k    nc S | j        dk    r!|| j        cxk    o| j        cxk    o|k    nc S || j        cxk    o| j        cxk    o|k    nc S t          d|j         d          )NFrG   rj   rk    )padr   r>   rC   rA   rB   rY   rm   rp   rQ   rr   rl   )r   r;   soft_marginrY   x_1y_1x_2y_2s           r$   is_inzInterval.is_in  s    	((K((eX&& 	OyEJ&&u C ;$*MMMMMMMMEIMMMMM ;$+BBBBBBBBBy)) 	OZ}-M-M 	O!&!2Cc3 	@9##$+444444444$+4444444449##$*????????C?????$*????????C????? M%/MMMNNNr&   Tr;   strictc           	      &   t          |t                    r| j        |j        k    rb| j        dk    r1|j        dk    r&t          | j        |j        | j        |j                  S t          |j        | j        |j        | j                  S |                     t          | j        |j                  t          | j        |j                  | j        | j	        | j
                  S t          |t                    r|j        \  }}}}| j        dk    r8t          t          || j                  |t          || j                  |          S | j        dk    r8t          |t          || j                  |t          || j                            S d	S t          |t                    r]|rt          d          t          j        d|j         dt           d           |                     |                                          S t%          d|j         d          )
 rG   rH     The intersection between an Interval and a Quadrilateral might generate Polygon shapes that are not supported in the current version of layoutparser. You can pass `strict=False` in the input that converts the Quadrilateral to Rectangle to avoid this Exception.(With `strict=False`, the other of shape  will be converted to  for obtaining the intersectionrj   rk   N)r   r>   rC   rm   rA   rB   rl   maxminrD   rE   rQ   rp   r   warningswarn	intersectrn   rr   r   r;   r   r{   r|   r}   r~   s          r$   r   zInterval.intersect+  s    eX&& "	OyEJ&&9##
c(9(9$TZdh	RRR$U[$*eiRRR~~
EK00%),,I&%   y)) 	O!&!2Cc3yC S$*!5!5sCTX<N<NPSTTTc!! c#tz&:&:CS$(ASASTTT "! }-- 	O <, [    Qu  Q  Qfo  Q  Q  Q   ~~e&8&8&:&:;;; M%/MMMNNNr&   c           	         t          |t                    rw| j        |j        k    rt          d          |                     t          | j        |j                  t          | j        |j                  | j        | j	        | j
                  S t          |t                    r|j        \  }}}}| j        dk    r8t          t          || j                  |t          || j                  |          S | j        dk    r8t          |t          || j                  |t          || j                            S d
S t          |t                    r]|rt          d          t          j        d|j         dt           d           |                     |                                          S t'          d|j         d	          )r   z8Unioning two intervals of different axes is not allowed.rG   rH   r   r   r   r   rj   rk   N)r   r>   rC   r   rl   r   rA   r   rB   rD   rE   rm   rQ   rp   r   r   r   unionrn   rr   r   s          r$   r   zInterval.unionS  s    eX&& !	OyEJ&&'O   ~~
EK00%),,I&%   y)) 	O!&!2Cc3yC S$*!5!5sCTX<N<NPSTTTc!! c#tz&:&:CS$(ASASTTT "! }-- 	O 8, [    Qu  Q  Qfo  Q  Q  Q   zz%"4"4"6"6777 M%/MMMNNNr&   r   c                 P   | j         dk    r:| j        |z
  }| j        |z   }|s|r!t          j        d| j        j                    n9| j        |z
  }| j        |z   }|s|r!t          j        d| j        j                    |rt          d|          }|                     ||          S )NrG   z)Invalid padding top/bottom for an x axis z(Invalid padding right/left for a y axis r   rX   )	rC   rA   rB   r   r   rl   __name__r   rc   )r   leftrighttopbottom	safe_moderA   rB   s           r$   ry   zInterval.pady  s    9J%E(U"C f Y@WYY   J$E(V#C u Xt~?VXX    	"5MMExxex---r&   c                     t          |t                    r8| j        dk    r|d         n|d         }t          j        d| j         d           | j        |z   }| j        |z   }|                     ||          S )a5  
        Shift the interval by a user specified amount along the same axis that the interval is defined on.

        Args:
            shift_distance (:obj:`numeric`): The number of pixels used to shift the interval.

        Returns:
            :obj:`BaseCoordElement`: The shifted Interval object.
        rG   r   r   z=Input shift for multiple axes. Only use the distance for the  axisrX   r   r	   rC   r   r   rA   rB   rc   )r   shift_distancerA   rB   s       r$   shiftzInterval.shift  s     nh// 	%)Y#%5%5q!!>!;L  M`PTPY```   
^+h'xxex---r&   c                     t          |t                    r8| j        dk    r|d         n|d         }t          j        d| j         d           | j        |z  }| j        |z  }|                     ||          S )a6  
        Scale the layout element by a user specified amount the same axis that the interval is defined on.

        Args:
            scale_factor (:obj:`numeric`): The amount for downscaling or upscaling the element.

        Returns:
            :obj:`BaseCoordElement`: The scaled Interval object.
        rG   r   r   z;Input scale for multiple axes. Only use the factor for the r   rX   r   )r   scale_factorrA   rB   s       r$   scalezInterval.scale  s     lH-- 	.2i3.>.><??LQROLM^di^^^   
\)h%xxex---r&   c                     |                      |          j        \  }}}}|t          |          t          |          t          |          t          |          f         S r   )rg   rQ   intr   imager{   r|   r}   r~   s         r$   
crop_imagezInterval.crop_image  sS    !//66BS#sSXXC(#c((SXX*==>>r&   c                     t          | j         S )z
        Convert the Interval to a Rectangle element.

        Returns:
            :obj:`Rectangle`: The converted Rectangle object.
        rm   rQ   rK   s    r$   rn   zInterval.to_rectangle  s     $*++r&   c                 *    t          | j                  S )z
        Convert the Interval to a Quadrilateral element.

        Returns:
            :obj:`Quadrilateral`: The converted Quadrilateral object.
        rp   rT   rK   s    r$   rq   zInterval.to_quadrilateral  s     T[)))r&   NNTr   r   r   r   T)r   
__module____qualname__r1   _name	_featuresrI   propertyrL   rN   rQ   rT   rY   r[   rg   r<   ro   rv   r   r   boolr   r   ry   r   r   r   rn   rq   rx   r&   r$   r>   r>   S   s6        " EIIII
. 
. 
. 
. ) ) X) ) ) X)   X" 	; 	; X	; - - X- ( ( X(9 9 94 O O O* O O O* ')% O O O O< %O %O/ %O %O %O %O %ON #O #O+ #OT #O #O #O #OJ. . . .,. . ... . .*? ? ?, , ,* * * * *r&   r>   c                   ^   e Zd ZdZdZg dZd Zed             Zed             Z	ed             Z
ed             Zed	             Zed
             Zed             Zed             Zei dfd            Zeddedefd            Zeddedefd            ZddZddZd dZd Zd Zd ZdS )!rm   a  
    This class describes the coordinate system of an axial rectangle box using two points as indicated below::

            (x_1, y_1) ----
            |             |
            |             |
            |             |
            ---- (x_2, y_2)

    Args:
        x_1 (:obj:`numeric`):
            x coordinate on the horizontal axis of the upper left corner of the rectangle.
        y_1 (:obj:`numeric`):
            y coordinate on the vertical axis of the upper left corner of the rectangle.
        x_2 (:obj:`numeric`):
            x coordinate on the horizontal axis of the lower right corner of the rectangle.
        y_2 (:obj:`numeric`):
            y coordinate on the vertical axis of the lower right corner of the rectangle.
    	rectangler{   r|   r}   r~   c                 >    || _         || _        || _        || _        d S r   r   )r   r{   r|   r}   r~   s        r$   rI   zRectangle.__init__  s"    r&   c                      | j         | j        z
  S )z
        Calculate the height of the rectangle.

        Returns:
            :obj:`numeric`: Output the numeric value of the height.
        )r~   r|   rK   s    r$   rL   zRectangle.height       x$(""r&   c                      | j         | j        z
  S )z
        Calculate the width of the rectangle.

        Returns:
            :obj:`numeric`: Output the numeric value of the width.
        )r}   r{   rK   s    r$   rN   zRectangle.width  r   r&   c                 6    | j         | j        | j        | j        fS )z
        Return the coordinates of the two points that define the rectangle.

        Returns:
            :obj:`Tuple(numeric)`: Output the numeric values of the coordinates in a Tuple of size four.
        r   rK   s    r$   rQ   zRectangle.coordinates  s     $(DHdh77r&   c                 *    t          | j                  S )z
        Return the coordinates of all four corners of the rectangle in a clockwise fashion
        starting from the upper left.

        Returns:
            :obj:`Numpy array`: A Numpy array of shape 4x2 containing the coordinates.
        rS   rK   s    r$   rT   zRectangle.points  rU   r&   c                 J    | j         | j        z   dz  | j        | j        z   dz  fS )z
        Calculate the center of the rectangle.

        Returns:
            :obj:`Tuple(numeric)`: Returns of coordinate of the center.
        rW   )r{   r}   r|   r~   rK   s    r$   rY   zRectangle.center  s+     48#s*TX-@C,GGGr&   c                      | j         | j        z  S )z3
        Return the area of the rectangle.
        )rN   rL   rK   s    r$   r[   zRectangle.area*  s    
 zDK''r&   c                 ^   t          |t                    rV|j        dk    r
|j        d}}n	d|j        }}|                     | j        |z   | j        |z   | j        |z   | j        |z             S t          |t                    rD|j
        \  }}}}|                     | j        |z   | j        |z   | j        |z   | j        |z             S t          |t                    r=t          |j        | j        d          }|                    || j        | j                  S t#          d|j         d          NrG   r   Tis_invrj   rk   r   r>   rC   rA   rl   r{   r|   r}   r~   rm   rQ   rp   r   perspective_matrixrT   rL   rN   rr   r   r;   dxdy_transformed_pointss         r$   ro   zRectangle.condition_on1  s@    eX&& 	OzS  aBEKB>>2tx"}dhmTX]   y)) 	O ,LBAq>>2tx"}dhmTX]   }-- 	O!;($+d" " " ??#5t{DJOOO M%/MMMNNNr&   c                 ^   t          |t                    rV|j        dk    r
|j        d}}n	d|j        }}|                     | j        |z
  | j        |z
  | j        |z
  | j        |z
            S t          |t                    rD|j
        \  }}}}|                     | j        |z
  | j        |z
  | j        |z
  | j        |z
            S t          |t                    r=t          |j        | j        d          }|                    || j        | j                  S t#          d|j         d          NrG   r   Fr   rj   rk   r   r   s         r$   rv   zRectangle.relative_toO  s>   eX&& 	OzS  aBEKB>>2tx"}dhmTX]   y)) 	O ,LBAq>>2tx"}dhmTX]   }-- 	O!;($+e" " " ??#5t{DJOOO M%/MMMNNNr&   Fc                 8    j         d
i |t          t                    r|sIj        dk    r| j        | j        }}n| j        | j        }}j        |cxk    o|cxk    o
j	        k    nc S j        dk    r| j
        d         n| j
        d         }j        |cxk    o
j	        k    nc S t          t                    rZ                    d          }                    d          }|                     ||          o|                     ||          S t          t                    rR|s"fd| j        D             }	t!          |	          S t#          j        | j
                  }t'          |j                  S t)          dj         d	          )NrG   r   r   rC   rH   rY   c                 :    g | ]}t          |j                  S rx   r   rT   .0verticer;   s     r$   
<listcomp>z#Rectangle.is_in.<locals>.<listcomp>  3     ! ! !BI&w==! ! !r&   rj   rk   rx   )ry   r   r>   rC   r{   r}   r|   r~   rA   rB   rY   rm   to_intervalr   rp   rT   allr^   arrayr   rr   rl   
r   r;   rz   rY   rA   rB   c
x_interval
y_intervalis_vertice_ins
    `        r$   r   zRectangle.is_inl  s    	((K((eX&&  	O 5:$$!%483EE!%483E{e????s????ei?????&+jC&7&7DKNNT[^{a44445944444y)) 	O***44J***44J::j:88 TZZ6 >H > >  }-- 	O 	@! ! ! !MQ[! ! ! =)))$+..)&%,??? M%/MMMNNNr&   Tr;   r   c           	         t          |t                    r|                    |           S t          |t                    rx|                     t          | j        |j                  t          | j        |j                  t          | j	        |j	                  t          | j
        |j
                            S t          |t                    r]|rt          d          t          j        d|j         dt           d           |                     |                                          S t!          d|j         d          )r   a  The intersection between a Rectangle and a Quadrilateral might generate Polygon shapes that are not supported in the current version of layoutparser. You can pass `strict=False` in the input that converts the Quadrilateral to Rectangle to avoid this Exception.r   r   r   rj   rk   )r   r>   r   rm   rl   r   r{   r|   r   r}   r~   rp   r   r   r   rn   rr   r   r;   r   s      r$   r   zRectangle.intersect  sJ    eX&& 	O??4(((y)) 	O>>DHei((DHei((DHei((DHei((	   }-- 	O <, [    Qu  Q  Qfo  Q  Q  Q   ~~e&8&8&:&:;;; M%/MMMNNNr&   c           	         t          |t                    r|                    |           S t          |t                    rx|                     t          | j        |j                  t          | j        |j                  t          | j	        |j	                  t          | j
        |j
                            S t          |t                    r]|rt          d          t          j        d|j         dt           d           |                     |                                          S t#          d|j         d          )r   r   r   r   r   rj   rk   )r   r>   r   rm   rl   r   r{   r|   r   r}   r~   rp   r   r   r   r   rn   rr   r   s      r$   r   zRectangle.union  sJ    eX&& 	O??4(((y)) 	O>>DHei((DHei((DHei((DHei((	   }-- 	O 8, [    Qu  Q  Qfo  Q  Q  Q   zz%"4"4"6"6777 M%/MMMNNNr&   r   c                     | j         |z
  }| j        |z
  }| j        |z   }| j        |z   }	|r t	          d|          }t	          d|          }|                     ||||	          S )Nr   )r{   r|   r}   r~   r   rl   )
r   r   r   r   r   r   r{   r|   r}   r~   s
             r$   ry   zRectangle.pad  sj    hohnhh 	a++Ca++C~~c3S111r&   c                     t          |t                    s|}|}n"t          |          dk    s
J d            |\  }}| j        |z   }| j        |z   }| j        |z   }| j        |z   }|                     ||||          S )Nr]   Rshift_distance should have 2 elements, one for x dimension and one for y dimensionr   r	   lenr{   r|   r}   r~   rl   )r   r   shift_xshift_yr{   r|   r}   r~   s           r$   r   zRectangle.shift  s    .(33 	.$G$GG N##q(((c )((-GWh h h h ~~c3S111r&   r   c                     t          |t                    s|}|}n"t          |          dk    s
J d            |\  }}| j        |z  }| j        |z  }| j        |z  }| j        |z  }|                     ||||          S )Nr]   Pscale_factor should have 2 elements, one for x dimension and one for y dimensionr   )r   r   scale_xscale_yr{   r|   r}   r~   s           r$   r   zRectangle.scale  s    ,11 	,"G"GG L!!Q&&&a '&&+GWh h h h ~~c3S111r&   c                     | j         \  }}}}|t          |          t          |          t          |          t          |          f         S r   )rQ   r   r   s         r$   r   zRectangle.crop_image  sE    !-S#sSXXC(#c((SXX*==>>r&   c                 h    |dk    r| j         | j        }}n| j        | j        }}t	          ||fd|i|S NrG   rC   )r{   r}   r|   r~   r>   )r   rC   r!   rA   rB   s        r$   r   zRectangle.to_interval   sD    3;;483EE483Es888888r&   c                 *    t          | j                  S r   r   rK   s    r$   rq   zRectangle.to_quadrilateral  s    T[)))r&   Nr   r   r   r   )r   r   r   r1   r   r   rI   r   rL   rN   rQ   rT   rY   r[   r<   ro   rv   r   r   r   r   r   ry   r   r   r   r   rq   rx   r&   r$   rm   rm     s.        ( E,,,I   # # X# # # X# 8 8 X8 	; 	; X	; H H XH ( ( X( O O O: O O O8 ')% $O $O $O $OL O O/ O O O O O: O O+ OT O O O O62 2 2 22 2 2 2"2 2 2 2"? ? ?9 9 9* * * * *r&   rm   c                       e Zd ZdZdZg dZ	 d%deej        e	e	e	         f         fdZ
ed             Zed             Zed	             Zed
             Zed             Zed             Zed             Zed             Zd Zed             Zed             Zei dfd            Zed&dedefd            Zed&dedefd            Zd'dZd(dZd)dZd Z d Z!d  Z"d! Z#d" Z$d#e%e&e'f         f fd$Z( xZ)S )*rp   a  
    This class describes the coodinate system of a four-sided polygon. A quadrilateral is defined by
    the coordinates of its 4 corners in a clockwise order starting with the upper left corner (as shown below)::

        points[0] -...- points[1]
        |                      |
        .                      .
        .                      .
        .                      .
        |                      |
        points[3] -...- points[2]

    Args:
        points (:obj:`Numpy array` or `list`):
            A `np.ndarray` of shape 4x2  for four corner coordinates
            or a list of length 8 for in the format of
            `[p0_x, p0_y, p1_x, p1_y, p2_x, p2_y, p3_x, p3_y]`
            or a list of length 4 in the format of
            `[[p0_x, p0_y], [p1_x, p1_y], [p2_x, p2_y], [p3_x, p3_y]]`.
        height (:obj:`numeric`, `optional`, defaults to `None`):
            The height of the quadrilateral. This is to better support the perspective
            transformation from the OpenCV library.
        width (:obj:`numeric`, `optional`, defaults to `None`):
            The width of the quadrilateral. Similarly as height, this is to better support the perspective
            transformation from the OpenCV library.
    quadrilateral)rT   rL   rN   NrT   c                 T   t          |t          j                  r$|j        dk    rt	          d|j         d          nt          |t
                    rt          |          dk    r)t          j        |                              dd          }nt          |          dk    r0t          |d         t
                    rt          j        |          }n@t	          dt          |           d	          t	          d
t          |           d          || _
        || _        || _        d S )N)   r]   zInvalid points shape: .   r   r]   r   z!Invalid number of points element z. Should be 8.zInvalid input type for points z-.Please make sure it is a list of np.ndarray.)r   r^   r_   r`   
ValueErrorlistr   r   reshapetype_points_width_height)r   rT   rL   rN   s       r$   rI   zQuadrilateral.__init__,  s0    fbj)) 	|v%% !I&,!I!I!IJJJ &%% 	6{{a&))11!Q77V!!jD&A&A!&)) SFSSS   ?f ? ? ?  
 r&   c                     | j         | j         S | j        dddf                                         | j        dddf                                         z
  S )z
        Return the user defined height, otherwise the height of its circumscribed rectangle.

        Returns:
            :obj:`numeric`: Output the numeric value of the height.
        Nr   )r   rT   r   r   rK   s    r$   rL   zQuadrilateral.heightF  sU     <#<{111a4 $$&&QQQT):)>)>)@)@@@r&   c                     | j         | j         S | j        dddf                                         | j        dddf                                         z
  S )z
        Return the user defined width, otherwise the width of its circumscribed rectangle.

        Returns:
            :obj:`numeric`: Output the numeric value of the width.
        Nr   )r   rT   r   r   rK   s    r$   rN   zQuadrilateral.widthS  sU     ;";{111a4 $$&&QQQT):)>)>)@)@@@r&   c                 *    t          | j                  S )a  
        Return the coordinates of the upper left and lower right corners points that
        define the circumscribed rectangle.

        Returns
            :obj:`Tuple(numeric)`: Output the numeric values of the coordinates in a Tuple of size four.
        )r   rT   rK   s    r$   rQ   zQuadrilateral.coordinates`  s     )555r&   c                     | j         S )z
        Return the coordinates of all four corners of the quadrilateral in a clockwise fashion
        starting from the upper left.

        Returns:
            :obj:`Numpy array`: A Numpy array of shape 4x2 containing the coordinates.
        )r   rK   s    r$   rT   zQuadrilateral.pointsl  s     |r&   c                 v    t          | j                            d                                                    S )z
        Calculate the center of the quadrilateral.

        Returns:
            :obj:`Tuple(numeric)`: Returns of coordinate of the center.
        r   r   )tuplerT   meantolistrK   s    r$   rY   zQuadrilateral.centerx  s1     T[%%1%--4466777r&   c                 ^    t          | j        dddf         | j        dddf                   S )z7
        Return the area of the quadrilateral.
        Nr   r   )r   rT   rK   s    r$   r[   zQuadrilateral.area  s2    
 DK1-t{111a4/@AAAr&   c                 r    dd| j         | j         d}dd| j        | j        d}|                     ||          S )Nr   r   r   r]      )rN   rL   map_to_points_ordering)r   x_mapy_maps      r$   mapped_rectangle_pointsz%Quadrilateral.mapped_rectangle_points  sD     !
tz::!<<**5%888r&   c                     t          | j                            d          | j                            d                    S )Nfloat32)_getPerspectiveTransformrT   astyper
  rK   s    r$   r   z Quadrilateral.perspective_matrix  s;    'Ky))(//	::
 
 	
r&   c                 >   | j                             d                              d          }t          j         t          j        |j                  |d d df                    t          j        |j                  |d d df                   g          j        S )Nr   r   r   )rT   argsortr^   vstack	vectorizegetT)r   r  r	  points_orderings       r$   r  z$Quadrilateral.map_to_points_ordering  s    +--1-55==1=EE y'UY''1(=>>'UY''1(=>>
 

 	r&   c                    t          |t                    rC|j        dk    r|                     |j        dg          S |                     d|j        g          S t          |t
                    r!|                     |j        |j        g          S t          |t                    r=t          |j
        | j        d          }|                     || j        | j                  S t          d|j         d          r   r   r>   rC   r   rA   rm   r{   r|   rp   r   r   rT   rl   rL   rN   rr   r   r;   r   s      r$   ro   zQuadrilateral.condition_on  s     eX&& 	OzS  zz5;"2333zz1ek"2333y)) 	O::uy%)4555}-- 	O!;($+d" " " >>"4dk4:NNN M%/MMMNNNr&   c                    t          |t                    rE|j        dk    r|                     |j         dg          S |                     d|j         g          S t          |t
                    r#|                     |j         |j         g          S t          |t                    r=t          |j
        | j        d          }|                     || j        | j                  S t          d|j         d          r   r  r  s      r$   rv   zQuadrilateral.relative_to  s     eX&& 	OzS  zzEK<"3444zz1u{l"3444y)) 	O::	zEI:6777}-- 	O!;($+e" " " >>"4dk4:NNN M%/MMMNNNr&   Fc                 h    j         di |t          t                    r|saj        dk    r| j        d         | j        d         }}n| j        d         | j        d         }}j        |cxk    o|cxk    o
j        k    nc S j        dk    r| j        d         n| j        d         }j        |cxk    o
j        k    nc S t          t                    rZ	                    d          }	                    d          }| 
                    ||          o| 
                    ||          S t          t                    rR|s"fd	| j        D             }	t          |	          S t          j        | j                  }t!          |j                  S t#          d
j         d          )NrG   r   r]   r   r  r   rH   r   c                 :    g | ]}t          |j                  S rx   r   r   s     r$   r   z'Quadrilateral.is_in.<locals>.<listcomp>  r   r&   rj   rk   rx   )ry   r   r>   rC   rQ   rA   rB   rY   rm   r   r   rp   rT   r   r^   r   r   rr   rl   r   s
    `        r$   r   zQuadrilateral.is_in  s    	((K((eX&&  	O 5:$$!%!1!!4d6Fq6I3EE!%!1!!4d6Fq6I3E{e????s????ei?????&+jC&7&7DKNNT[^{a44445944444y)) 	O***44J***44J::j:88 TZZ6 >H > >  }-- 	O 	@! ! ! !MQ[! ! ! =)))$+..)&%,??? M%/MMMNNNr&   Tr;   r   c                    |rt          d          t          |t                    st          |t                    rDt	          j        dt           d           |                    |                                           S t          |t                    rVt	          j        dt           d           |                                                     |                                          S t          d|j
         d          r   a  The intersection between a Quadrilateral and other objects might generate Polygon shapes that are not supported in the current version of layoutparser. You can pass `strict=False` in the input that converts the Quadrilateral to Rectangle to avoid this Exception.zKWith `strict=False`, the current Quadrilateral object will be converted to r   zKWith `strict=False`, both input Quadrilateral objects will be converted to rj   rk   )r   r   r>   rm   r   r   r   rn   rp   rr   rl   r   s      r$   r   zQuadrilateral.intersect  s'     	S( Y   %** Sj	.J.J S Mbk  M  M  M   t'8'8':':;;;E=11 S Mbk  M  M  M   ((**44U5G5G5I5IJJJ Qeo Q Q QRRRr&   c                    |rt          d          t          |t                    st          |t                    rDt	          j        dt           d           |                    |                                           S t          |t                    rVt	          j        dt           d           |                                                     |                                          S t          d|j
         d          r  )r   r   r>   rm   r   r   r   rn   rp   rr   rl   r   s      r$   r   zQuadrilateral.union  s'     	S( Y   %** Sj	.J.J S Mbk  M  M  M   {{4#4#4#6#6777E=11 S Mbk  M  M  M   ((**001C1C1E1EFFF Qeo Q Q QRRRr&   r   c                     | | ||d}| | ||d}|                      ||          }| j        |z   }	|rt          j        |	d          }	|                     |	          S )Nr  r   rT   )r  rT   r^   maximumrc   )
r   r   r   r   r   r   r  r	  padding_matrT   s
             r$   ry   zQuadrilateral.pad'  sz    Ete%88DcTf8811%??{* 	+Z**Fxxvx&&&r&   c                     t          |t                    s||g}nt          |          dk    s
J d            |}| j        t	          j        |          z   }|                     |          S )Nr]   r   r   r   r	   r   rT   r^   r   rc   )r   r   	shift_matrT   s       r$   r   zQuadrilateral.shift4  su    .(33 	''8II N##q(((c )((&Irx	222xxvx&&&r&   r   c                     t          |t                    s||g}nt          |          dk    s
J d            |}| j        t	          j        |          z  }|                     |          S )Nr]   r   r   r$  )r   r   	scale_matrT   s       r$   r   zQuadrilateral.scaleB  su    ,11 	%%|4II L!!Q&&&a '&&$Irx	222xxvx&&&r&   c                 z    t          || j        t          | j                  t          | j                  f          S )z
        Crop the input image using the points of the quadrilateral instance.

        Args:
            image (:obj:`Numpy array`): The array of the input image.

        Returns:
            :obj:`Numpy array`: The array of the cropped image.
        )_warpPerspectiver   r   rN   rL   r   r   s     r$   r   zQuadrilateral.crop_imageP  s7      4*S__c$+>N>N,O
 
 	
r&   c                 X    | j         \  }}}}|dk    r||}}n||}}t          ||fd|i|S r   )rQ   r>   )	r   rC   r!   r{   r|   r}   r~   rA   rB   s	            r$   r   zQuadrilateral.to_interval_  sM    !-S#s3;;c3EEc3Es888888r&   c                     t          | j         S r   r   rK   s    r$   rn   zQuadrilateral.to_rectanglei  s    $*++r&   c                     |j         | j         urdS t          j        | j        |j                                                  S )NF)rl   r^   iscloserT   r   r   r;   s     r$   __eq__zQuadrilateral.__eq__l  s8    ?$.005z$+u|4488:::r&   c                 r     g d}d                      fd|D                       } j        j         d| dS )N)rT   rN   rL   z, c                 :    g | ]}| d t          |           S )=)r4   )r   keyr   s     r$   r   z*Quadrilateral.__repr__.<locals>.<listcomp>s  s1    LLL;;wtS'9'9;;LLLr&   ())joinrl   r   )r   keysinfo_strs   `  r$   __repr__zQuadrilateral.__repr__q  sP    ,,,99LLLLtLLLMM.)77H7777r&   returnc                     t                                                      }|d                             d                                          |d<   |S )a  
        Generate a dictionary representation of the current object::

            {
                "block_type": "quadrilateral",
                "points": [
                    p[0,0], p[0,1],
                    p[1,0], p[1,1],
                    p[2,0], p[2,1],
                    p[3,0], p[3,1]
                ],
                "height": value,
                "width": value
            }
        rT   )superto_dictr   r  )r   datarl   s     r$   r?  zQuadrilateral.to_dictv  sD    " ww  h//33::<<Xr&   r   r   r   r   r   )*r   r   r   r1   r   r   r   r^   r_   r   rI   r   rL   rN   rQ   rT   rY   r[   r
  r   r  r<   ro   rv   r   r   r   r   r   ry   r   r   r   r   rn   r0  r:  r   strr   r?  __classcell__)rl   s   @r$   rp   rp     s        6 E---I OS BJd4j89   4 
A 
A X
A 
A 
A X
A 	6 	6 X	6 	 	 X	 8 8 X8 B B XB 9 9 X9 
 
 X

 
 
 O O O. O O O. ')% $O $O $O $OL S S/ S S S S S* S S+ ST S S S S(' ' ' '' ' ' '' ' ' '
 
 
9 9 9, , ,; ; ;
8 8 8
c3h          r&   rp   c                     i | ]
}|j         |S rx   r   )r   eles     r$   
<dictcomp>rF    s    NNNSYNNNr&   c                 $    i | ]\  }}|j         |S rx   rD  )r   idxrE  s      r$   rF  rF    s-       sCCIs  r&   c                      e Zd ZdZdZg dZ	 d!dZed             Zed             Z	ed             Z
ed	             Zed
             Zed             Zed             Zi dfdZed"dedefd            Zed"dedefd            Zed             Zed#d            Zed             Zd Zd$dee         fdZd Zd Zdeeef         fdZ e!deeef         dd fd             Z"dS )%r:   a  
    This class constructs content-related information of a layout element in addition to its coordinate definitions
    (i.e. Interval, Rectangle or Quadrilateral).

    Args:
        block (:obj:`BaseCoordElement`):
            The shape-specific coordinate systems that the text block belongs to.
        text (:obj:`str`, `optional`, defaults to None):
            The ocr'ed text results within the boundaries of the text block.
        id (:obj:`int`, `optional`, defaults to `None`):
            The id of the text block.
        type (:obj:`int`, `optional`, defaults to `None`):
            The type of the text block.
        parent (:obj:`int`, `optional`, defaults to `None`):
            The id of the parent object.
        next (:obj:`int`, `optional`, defaults to `None`):
            The id of the next block.
        score (:obj:`numeric`, defaults to `None`):
            The prediction confidence of the block
    	textblock)textidr   r7   nextscoreNc                     t          |t                    sJ || _        || _        || _        || _        || _        || _        || _        d S r   )	r   r   r   rK  rL  r   r7   rM  rN  )r   r   rK  rL  r   r7   rM  rN  s           r$   rI   zTextBlock.__init__  sP     %!122222
			


r&   c                     | j         j        S )z
        Return the height of the shape-specific block.

        Returns:
            :obj:`numeric`: Output the numeric value of the height.
        )r   rL   rK   s    r$   rL   zTextBlock.height  s     z  r&   c                     | j         j        S )z
        Return the width of the shape-specific block.

        Returns:
            :obj:`numeric`: Output the numeric value of the width.
        )r   rN   rK   s    r$   rN   zTextBlock.width  s     zr&   c                     | j         j        S )z
        Return the coordinates of the two corner points that define the shape-specific block.

        Returns:
            :obj:`Tuple(numeric)`: Output the numeric values of the coordinates in a Tuple of size four.
        )r   rQ   rK   s    r$   rQ   zTextBlock.coordinates  s     z%%r&   c                     | j         j        S )z
        Return the coordinates of all four corners of the shape-specific block in a clockwise fashion
        starting from the upper left.

        Returns:
            :obj:`Numpy array`: A Numpy array of shape 4x2 containing the coordinates.
        )r   rT   rK   s    r$   rT   zTextBlock.points  s     z  r&   c                     | j         j        S )z6
        Return the area of associated block.
        )r   r[   rK   s    r$   r[   zTextBlock.area  s    
 zr&   c                 6    | j                             |          S r   )r   ro   r/  s     r$   ro   zTextBlock.condition_on  s    z&&u---r&   c                 6    | j                             |          S r   )r   rv   r/  s     r$   rv   zTextBlock.relative_to  s    z%%e,,,r&   Fc                 :    | j                             |||          S r   )r   r   )r   r;   rz   rY   s       r$   r   zTextBlock.is_in  s    z{F;;;r&   Tr;   r   c                 :    | j                             ||          S N)r   )r   r   r   s      r$   r   zTextBlock.union  s    zf555r&   c                 :    | j                             ||          S rY  )r   r   r   s      r$   r   zTextBlock.intersect  s    z##E&#999r&   c                 6    | j                             |          S r   )r   r   )r   r   s     r$   r   zTextBlock.shift  s    z///r&   r   c                 >    | j                             |||||          S r   )r   ry   )r   r   r   r   r   r   s         r$   ry   zTextBlock.pad  s    z~~dE3	BBBr&   c                 6    | j                             |          S r   )r   r   )r   r   s     r$   r   zTextBlock.scale  s    z---r&   c                 6    | j                             |          S r   )r   r   r*  s     r$   r   zTextBlock.crop_image  s    z$$U+++r&   rC   c                     t          | j        t                    r| S |st          dd d          |                      | j        j        dd|i|          S )Nz#Please provide valid `axis` values rG   rH   z as the inputrC   r   rx   )r   r   r>   r   rc   r   )r   rC   r!   s      r$   r   zTextBlock.to_interval  su    dj(++ 	OK  S#SSS   88"8$*"8"M"Md"Mf"M"M8NNNr&   c                     t          | j        t                    r| S |                     | j                                                  S Nr`  )r   r   rm   rc   rn   rK   s    r$   rn   zTextBlock.to_rectangle  s=    dj),, 	=K88$*"9"9";";8<<<r&   c                     t          | j        t                    r| S |                     | j                                                  S rb  )r   r   rp   rc   rq   rK   s    r$   rq   zTextBlock.to_quadrilateral"  s>    dj-00 	AK88$*"="="?"?8@@@r&   r;  c                     | j                                         }| j        D ]'}t          | |          }|t          | |          ||<   (|S )a  
        Generate a dictionary representation of the current textblock of the format::

            {
                "block_type": <name of self.block>,
                <attributes of self.block combined with
                    non-empty self._features>
            }
        )r   r?  r   r4   )r   	base_dictfvals       r$   r?  zTextBlock.to_dict(  sV     J&&((	 	0 	0A$""C&tQ//	!r&   r@  c                     d         t           v sJ dd                      t           d                                                } | |fi fd| j        D             S )a/  Initialize the textblock based on the dictionary representation.
        It generate the block based on the `block_type` and `block_attr`,
        and loads the textblock specific features from the dict.

        Args:
            data (:obj:`dict`): The dictionary representation of the object
        
block_typezInvalid block_type c                 >    i | ]}|                     |d           S r   )r  )r   rf  r@  s     r$   rF  z'TextBlock.from_dict.<locals>.<dictcomp>H  s)    IIIaQD 1 1IIIr&   )BASECOORD_ELEMENT_NAMEMAP	from_dictr   )r5   r@  r   s    ` r$   rl  zTextBlock.from_dict9  s     ";;;;5l!355 <;; *$|*<=GGMMs5JJIIII3=IIIJJJr&   )NNNNNNr   r   r   )#r   r   r   r1   r   r   rI   r   rL   rN   rQ   rT   r[   r+   ro   rv   r   r   r   r   r   r   ry   r   r   r   rA  r   rn   rq   r   r   r?  classmethodrl  rx   r&   r$   r:   r:     s        * EAAAI SW    ! ! X!     X  & & X& 	! 	! X	!   X . . . - - - (*% < < < < 6 6+ 6T 6 6 6 6 : :/ : : : : : 0 0 0 C C C C . . ., , ,O O O O O O= = =A A Ac3h    " KT#s(^ K K K K [K K Kr&   r:   r   )1typingr   r   r   r   r   r   collections.abcr	   r
   inspectr   r   r   r(   numpyr^   pandaspdPILr   cv2r   r  r   r)  baser   r   utilsr   r   r   r   r   errorsr   r   r+   r0   r<   r>   rm   rp   ALL_BASECOORD_ELEMENTSrk  	enumerateBASECOORD_ELEMENT_INDEXMAPr:   rx   r&   r$   <module>r|     s	   A @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ $ $ $ $ $ $       * * * * * * * *                    C C C C C C 3 3 3 3 3 3 5 5 5 5 5 5 5 5              > = = = = = = =	 	 	t     *   {* {* {* {* {* {* {* {*| v* v* v* v* v*  v* v* v*r	 | | | | |$ | | |~ #I}= NN7MNNN  #,9-C#D#D   
 /000sK sK sK sK sK! sK sK 10sK sK sKr&   