
    j!                        d dl mZ 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 d dlmZ g dZdej        d	efd
Z	 	 	 	 	 ddej        deeef         dz  dedededed	efdZdeej                 dee         d	eej                 fdZdej        dee         d	ej        dz  fdZded	eeef         fdZdeeeef                  eeee         f         z  d	eeeef                  eeee         f         z  fdZdS )     )floor)
median_low)AnyN)LangDetectExceptiondetect_langs)rotate_image)estimate_orientationget_languageinvert_data_structurecontourreturnc                     t          j        |           \  }\  }}}|dk    s|dk    rdS t          ||z  ||z            S )zGet the maximum shape ratio of a contour.

    Args:
        contour: the contour from cv2.findContour

    Returns:
        the maximum shape ratio
    r           )cv2minAreaRectmax)r   _whs       V/var/www/html/Carbon-Document/venv/lib/python3.11/site-packages/doctr/models/_utils.pyget_max_width_length_ratior      sK     ?7++LAv1qAvvasq1ua!e    F      皙?d   imggeneral_page_orientationn_ctratio_threshold_for_linesmin_confidence
lower_areac                    t          | j                  dk    r| j        d         dv sJ d| j         d            | j        d         dk    rjt          j        | t          j                  }t          j        |d          }t          j        |ddt          j        t          j        z   	          d
         }n| 	                    t          j                  }|pd\  }}	|duo|	|k    }
|
r|nd}|
rt          ||           }n| j        dd         \  }}t          d
t          |dz                      }t          d
t          |dz                      }t          j        t          j        ||f          }t          j        ||d
          }t          j        |t          j        t          j                  \  }}t+          fd|D             t,          d          }g }|d|         D ]}t          j        |          \  }\  }}}||k     r	||}}|dz  }|dk    r|dz  }|dk    |dk    r|dz  }|dk    |dk    rC||z  |k    r|                    |           s||z  d
|z  k     r|                    |dz
             t          |          dk    rd}nJt3          |           }t5          |          dk    rt7          |           nd}t5          |          dk    rd}||z   }|dk    r|dz  }|dk    |dk    r|dz  }|dk    |
r@t5          |          dz  dk    r|S t5          |          t5          |          k    r|dk    r|S t9          |          S )a&  Estimate the angle of the general document orientation based on the
     lines of the document and the assumption that they should be horizontal.

    Args:
        img: the img or bitmap to analyze (H, W, C)
        general_page_orientation: the general orientation of the page (angle [0, 90, 180, 270 (-90)], confidence)
            estimated by a model
        n_ct: the number of contours used for the orientation estimation
        ratio_threshold_for_lines: this is the ratio w/h used to discriminates lines
        min_confidence: the minimum confidence to consider the general_page_orientation
        lower_area: the minimum area of a contour to be considered

    Returns:
        the estimated angle of the page (clockwise, negative for left side rotation, positive for right side rotation)
    r   )   r   zImage shape z not supported   r      )threshmaxvaltyper%   )r   r   N   r   )
iterationsc                 D    g | ]}t          j        |          k    |S  )r   contourArea).0r   r"   s     r   
<listcomp>z(estimate_orientation.<locals>.<listcomp>X   s-    RRRWCOG,D,Dz,Q,Q,Q,Q,Qr   T)keyreverseZ   i   ih  iL)lenshaper   cvtColorCOLOR_BGR2GRAY
medianBlur	thresholdTHRESH_BINARY_INVTHRESH_OTSUastypenpuint8r   r   r   getStructuringElement
MORPH_RECTdilatefindContours	RETR_LISTCHAIN_APPROX_SIMPLEsortedr   r   appendr   absroundint)r   r   r   r    r!   r"   gray_imgr(   page_orientationorientation_confidenceis_confident
base_angler   r   k_xk_ykernelcontoursr   anglesr   angle
skew_anglemedianfinal_angles        `                   r   r	   r	   "   s   . sy>>Q39R=F#:#:#:<d39<d<d<d#:#:: y}<S%788>(A..x#CDY\_\kDklllmnoBH%%/G/S8,,#4/\4Jn4\L%18!!qJ 
: fzk22 2A2A!eAGnn&&!eAGnn&&*3>C:FFFFq999 "63=#:QRRKHa RRRRRRR&  H FETE? * *?7336Aq5
 q55aqARKE sllSLE sllbjjSLE bjj q551u000e$$$$Q6666ebj)))
6{{a

 V$$$'*6{{a'7'7eFmm^^Q
 z??b  J z)K 

s 




s 

  
$z??R1$$## z??c"233338HA8M8M##  r   cropsorientationsc                 x    d |D             }t          |          dk    rd t          ||           D             ng S )zRotate each crop of the list according to the predicted orientation:
    0: already straight, no rotation
    1: 90 ccw, rotate 3 times ccw
    2: 180, rotate 2 times ccw
    3: 270 ccw, rotate 1 time ccw
    c                 (    g | ]}|d k    rd|z
  nd S )r      r.   )r0   preds     r   r1   z!rectify_crops.<locals>.<listcomp>   s(    JJJT		AHHqJJJr   r   c                 N    g | ]"\  }}|d k    r|nt          j        ||          #S )r   )r?   rot90)r0   orientationcrops      r   r1   z!rectify_crops.<locals>.<listcomp>   s8    uuuGX{TX!!rxk'B'Buuur   )r6   zip)rZ   r[   s     r   rectify_cropsre      sY     KJ\JJJL |q   	vu\_`lns\t\tuuuur   page_loc_predsc                     t          |          dk    r.t          j        d t          ||           D             d          ndS )zOrient the quadrangle (Polygon4P) according to the predicted orientation,
    so that the points are in this order: top L, top R, bot R, bot L if the crop is readable
    r   c                 B    g | ]\  }}t          j        ||d           S )r   axis)r?   roll)r0   rb   page_loc_preds      r   r1   z%rectify_loc_preds.<locals>.<listcomp>   s=       .K {;;;  r   ri   N)r6   r?   stackrd   )rf   r[   s     r   rectify_loc_predsrn      sg     |q   	 25lN2S2S   	
 	
 	
 	
 
r   textc                     	 t          |                                           d         }n# t          $ r Y dS w xY wt          |           dk    st          |           dk    r|j        dk    rdS |j        |j        fS )a  Get languages of a text using langdetect model.
    Get the language with the highest probability or no language if only a few words or a low probability

    Args:
        text (str): text

    Returns:
        The detected language in ISO 639 code and confidence score
    r   )unknownr   r%   r&   r   )r   lowerr   r6   problang)ro   rt   s     r   r
   r
      s    DJJLL))!,   ~~
4yyA~~#d))q..TY#-=-=~9dis   '* 
88xc                     t           t                    r`t          d                                  D                       dk    s
J d             fdt	                                            D             S t           t
                    r fd d         D             S t          dt          t                     d          )	aK  Invert a list of dict of elements to a dict of list of elements and the other way around

    Args:
        x: a list of dictionaries with the same keys or a dictionary of lists of the same length

    Returns:
        dictionary of list when x is a list of dictionaries or a list of dictionaries when x is dictionary of lists
    c                 ,    h | ]}t          |          S r.   )r6   )r0   vs     r   	<setcomp>z(invert_data_structure.<locals>.<setcomp>   s    ///qCFF///r   r%   z<All the lists in the dictionary should have the same length.c                 J    g | ]}t          t          |                     S r.   )dictrd   )r0   tru   s     r   r1   z)invert_data_structure.<locals>.<listcomp>   s'    :::ASAYY:::r   c                 0    i | ]fd D             S )c                      g | ]
}|         S r.   r.   )r0   dicks     r   r1   z4invert_data_structure.<locals>.<dictcomp>.<listcomp>   s    (((sCF(((r   r.   )r0   r   ru   s    @r   
<dictcomp>z)invert_data_structure.<locals>.<dictcomp>   s1    777Q((((a(((777r   r   z2Expected input to be either a dict or a list, got z	 instead.)	
isinstancer{   r6   valuesrd   list	TypeErrorr*   input)ru   s   `r   r   r      s     !T e//AHHJJ///00A5557u555::::ahhjj)9::::	At		 e7777!A$7777cTRW[[cccdddr   )Nr   r   r   r   )mathr   
statisticsr   typingr   r   numpyr?   
langdetectr   r   doctr.utils.geometryr   __all__ndarrayfloatr   tuplerK   r	   r   re   rn   strr
   r{   r   r.   r   r   <module>r      sN         ! ! ! ! ! !       



     8 8 8 8 8 8 8 8 - - - - - -
K
K
K
 u    " :>'(v v	v#CJ/$6v v  %	v
 v v 	v v v vr
s) 
"*   &Js) Z$   ( s  uS%Z0        &eDcNd3S	>22e	$sCx.Dd3i00e e e e e er   