o
    ,h                     @   s  d dl mZ d dlZd dlZd dlZd dlZd dlZd dlm	Z	m
Z
 d dlmZ d dlZd dlZd dlZd dlmZ ddlmZ ejd  dkrNd d	lmZ nd d	lmZ dLddZddgddgdg dfddZG dd dZG dd dZdd ZdMddZdMddZdd Zdg fd d!Z G d"d# d#e!Z"d$d% Z#d&d' Z$dNd-d.Z%d/d0 Z&d1d2 Z'dOd4d5Z(dPd6d7Z)d8d9 Z*d:d; Z+dQd=d>Z,dRdBdCZ-dDdE Z.dSdFdGZ/dHdI Z0dJdK Z1dS )T    )print_functionN)ImageJpegImagePlugin)ndimage)ZipFile   )	loadImage   )urlretrievefirstc                 C   sf   t | t t | |kd d }dd |D }|dkr&dd |D }|S |dkr1dd |D }|S )	Nr   r   c                 S   s   g | ]
}t |d kr|qS r   len.0item r   H/var/www/html/scripts/venv/lib/python3.10/site-packages/easyocr/utils.py
<listcomp>       zconsecutive.<locals>.<listcomp>r   c                 S      g | ]}|d  qS r   r   r   lr   r   r   r          lastc                 S   r   )r   r   r   r   r   r      r   )npsplitwherediff)datamodestepsizegroupresultr   r   r   consecutive   s   $r%         )then)r   r	   r&   r'   c                    sF  g }g }d}d}|D ]&  d dkrd}nd}t t|  k |} fdd|D }	||	7 }q
t|dd	 d
}|D ]P}
| D ]I}|
d || d krT|}|
d }qA|
d || d kr||kr||d |
d d gg}||kr}|d||d gg |
d d }|| d}qAq;|t| d kr|d|t| d gg |S )Nr    r	   r   r   c                    s   g | ]}| gqS r   r   r   sep_idxr   r   r   %   r   z%word_segmentation.<locals>.<listcomp>c                 S      | d S Nr   r   xr   r   r   <lambda>'       z#word_segmentation.<locals>.<lambda>keyr   )r%   r   argwhereflattensortedkeysappendr   )matseparator_idxseparator_idx_listr$   sep_list	start_idxsep_langr!   anew_sepseplangsep_start_idxnew_sep_pairr   r+   r   word_segmentation   s:   


rF   c                   @   s   e Zd ZdZdd ZdS )	BeamEntryz7information about one single beam at specific time-stepc                 C   s.   d| _ d| _d| _d| _d| _d| _d| _d S )Nr   r   Fr   T)prTotal
prNonBlankprBlankprText	lmAppliedlabeling
simplifiedselfr   r   r   __init__>   s   
zBeamEntry.__init__N)__name__
__module____qualname____doc__rQ   r   r   r   r   rG   <   s    rG   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )	BeamStatez1information about the beams at specific time-stepc                 C   s
   i | _ d S N)entriesrO   r   r   r   rQ   I   s   
zBeamState.__init__c                 C   sL   | j  D ]\}}t| j | j}| j | jd|r|nd  | j | _qdS )zlength-normalise LM score      ?N)rX   itemsr   rM   rK   )rP   k_labelingLenr   r   r   normL   s   &zBeamState.normc                 C   s4   dd | j  D }t|ddd d}dd |D S )z,return beam-labelings, sorted by probabilityc                 S      g | ]\}}|qS r   r   r   r\   vr   r   r   r   T   r   z"BeamState.sort.<locals>.<listcomp>Tc                 S      | j | j S rW   rH   rK   r/   r   r   r   r1   U       z BeamState.sort.<locals>.<lambda>reverser4   c                 S   s   g | ]}|j qS r   )rM   )r   r0   r   r   r   r   V   s    )rX   rZ   r7   )rP   beamssortedBeamsr   r   r   sortR   s   zBeamState.sortc                 C   s   dd | j  D }t|ddd d}t||kr|d | }t|D ]:\}}|j}	d}
t|	D ]\}}||vrL|dkrF|	|d	  |	| ksL|
|| 7 }
q0|dkrS|
}|
|v r\|
} |S 	 q#|S )
Nc                 S   r_   r   r   r`   r   r   r   r   Y   r   z(BeamState.wordsearch.<locals>.<listcomp>Tc                 S   rb   rW   rc   r/   r   r   r   r1   Z   rd   z&BeamState.wordsearch.<locals>.<lambda>re   r*   r   r   )rX   rZ   r7   r   	enumeraterM   )rP   classes
ignore_idxmaxCandidate	dict_listrg   rh   j	candidateidx_listtextir   	best_textr   r   r   
wordsearchX   s"   $zBeamState.wordsearchN)rR   rS   rT   rU   rQ   r^   ri   ru   r   r   r   r   rV   G   s    rV   c                 C   sh   |r0|j s2|| jr| jd n|d }||jd  }d}|||| }| j| |_d|_ dS dS dS )zjcalculate LM score of child beam by taking score from parent beam and bigram probability of last two charsr    g{Gz?TN)rL   rM   indexgetCharBigramrK   )
parentBeam	childBeamrk   lmc1c2lmFactor
bigramProbr   r   r   applyLMn   s   

r   c                 C   s   t | } t t | d| k| |k@  d }| | } t t | dt | dk| |k@  d }t| dkrHt| d }||vrHt ||g}| | } t| S )Nr   r   r   )r   arrayr   rollr   r9   tuple)rM   blankIdxidxlast_idxr   r   r   simplify_labelx   s   
$,r   c                 C   s   | r||kr| d |kr| |f }|S | r7||kr7| d |kr7| d |kr,| |f }|S | d d |f }|S | rG||krG| d |krG| }|S | sQ||krQ| }|S | s^||kr^| |f }|S | rk||krk| |f }|S | |f }t ||}|S )Nr   )r   )rM   cr   newLabelingr   r   r   fast_simplify_label   s0   
!





r   c                 C   s   || j vrt | j |< dS dS )z!add beam if it does not yet existN)rX   rG   )	beamStaterM   r   r   r   addBeam   s   
r      c                 C   sj  d}| j \}}t }	d}
t |	j|
< d|	j|
 _d|	j|
 _t|D ]}t }|	 d| }|D ]}
d}|
rE|	j|
 j| ||
d f  }|	j|
 j| ||f  }|
}|	j|
 j	s^t
|
|}
t||
 |
|j|
 _|j|
  j|7  _|j|
  j|7  _|j|
  j|| 7  _|	j| j|j|
 _t| |d d f d| kd }|D ]H}t|
||}|
r|
d |kr| ||f |	j| j }n| ||f |	j| j }t|| ||j| _|j|  j|7  _|j|  j|7  _qq1|}	q"|	  |g kr+|	 d }d}t|D ] \}}||vr'|dkr!||d  || ks'||| 7 }q|S |	||d|}|S )Nr   r   r   r         ?r*      )shaperV   rG   rX   rJ   rH   rangeri   rI   rN   r   r   rM   rK   r   r   r   r^   rj   ru   )r:   rk   rl   r{   	beamWidthrn   r   maxTmaxCr   rM   tcurrbestLabelingsrI   rJ   prev_labelingchar_highscorer   r   bestLabelingresrs   r   r   r   r   ctcBeamSearch   s^   


"

*r   c                   @   sD   e Zd ZdZi i fddZdddZdd Zdd
dZdddZdS )CTCLabelConverterz+ Convert between text-label and text-index c              	   C   sN  t |}i | _t|D ]\}}|d | j|< qdg| | _|| _g }| D ]\}}	||	7 }q&dgdd t|D  | _t|dkrvg }
| D ],\}}z#t|ddd}|	 
 }W d    n1 sew   Y  |
|7 }
W qH   Y qHn,i }
| D ]%\}}t|ddd}|	 
 }W d    n1 sw   Y  ||
|< q||
| _d S )	Nr   z[blank]r   c                 S   s   g | ]\}}|d  qS r   r   )r   rs   r   r   r   r   r   "      z.CTCLabelConverter.__init__.<locals>.<listcomp>rz	utf-8-sig)encoding)listdictrj   	characterseparator_listrZ   rl   r   openread
splitlinesrn   )rP   r   r   dict_pathlistdict_characterrs   charseparator_charrC   rB   rn   	dict_path
input_file
word_countr   r   r   rQ     s8   


zCTCLabelConverter.__init__r   c                    s>   dd |D }d |} fdd|D }t|t|fS )aV  convert text-label into text-index.
        input:
            text: text labels of each image. [batch_size]

        output:
            text: concatenated text index for CTCLoss.
                    [sum(text_lengths)] = [text_index_0 + text_index_1 + ... + text_index_(n - 1)]
            length: length of each text. [batch_size]
        c                 S   s   g | ]}t |qS r   r   )r   sr   r   r   r   A  r   z,CTCLabelConverter.encode.<locals>.<listcomp>r*   c                    s   g | ]} j | qS r   )r   )r   r   rO   r   r   r   C      )jointorch	IntTensor)rP   rr   batch_max_lengthlengthr   rO   r   encode7  s   

zCTCLabelConverter.encodec                 C   s   g }d}|D ]C}||||  }t |dd |dd k dd}t |t | j }||@ }	dt | j||	   }
||
 ||7 }q|S )z% convert text-index into text-label. r   r   Nr   Tr*   )	r   insertisinr   rl   r   r   nonzeror9   )rP   
text_indexr   textsrw   r   r   r@   br   rr   r   r   r   decode_greedyG  s   $

zCTCLabelConverter.decode_greedy   c                 C   s@   g }t |jd D ]}t|| | j| jd |d}|| q	|S )Nr   )r   )r   r   r   r   rl   r9   )rP   r:   r   r   rs   r   r   r   r   decode_beamsearchY  s
   z#CTCLabelConverter.decode_beamsearchc              
   C   sv  g }t j|dd}t|jd D ]}d}t| jdkrs| jd }t || |k }t 	|t 
t |dkd d }	dd |	D }	t|	D ])\}
}|||d d f }t|| j| jd || jd	}|
dkrk||7 }qH|d| 7 }qHn@t|| }|D ]7}|||d d |d d d d d f }|d dkrg }n| j|d  }t|| j| jd ||d	}||7 }q{|| q|S )
Nr	   )axisr   r*   rv   r   c                 S   s    g | ]}t |d krt|qS r   )r   r   r   r   r   r   r   l       z;CTCLabelConverter.decode_wordbeamsearch.<locals>.<listcomp>)r   rn   )r   argmaxr   r   r   r   r   r5   r6   r   r   r   rj   r   r   rl   rn   rF   r9   )rP   r:   r   r   r   rs   string	space_idxr    r#   ro   list_idxmatrixr   wordswordrn   r   r   r   decode_wordbeamsearch`  s4   
$	*
z'CTCLabelConverter.decode_wordbeamsearchN)r   r   )	rR   rS   rT   rU   rQ   r   r   r   r   r   r   r   r   r     s    
#
r   c                    s  g g }}|s	 S  t | d  } d t |   t D ]9\}}|t  d kr8|| || g }q|g ksF|d d |d k rL|| q|| g }|| q|D ]X}t |}t ||d  }	t|dd  D ]\}
}|d d d |d d d d k r|
} nqqt|| D ]\}
}|d d d |d d d k r|
}	 nq|| |	| q[g   fdd|D   S )Nr   r   r   c                    s   g | ]}  |qS r   )extend)r   r   merge_resultr   r   r     r   z!merge_to_free.<locals>.<listcomp>)r   rj   r9   r   )r   	free_listmerge_result_bufmr_buffree_list_bufr   r   free_posy_posx_posrs   
result_posr   r   r   merge_to_free  sB   



$ r   c                 C   s@  |\}}}}t |d |d  d |d |d  d  }t |d |d  d |d |d  d  }tt|t|}t |d |d  d |d |d  d  }	t |d |d  d |d |d  d  }
tt|	t|
}t jddg|d dg|d |d gd|d ggdd}t||}t| |||f}|S )Nr   r	   r   float32dtype)r   sqrtmaxintr   cv2getPerspectiveTransformwarpPerspective)imagerecttltrbrblwidthAwidthBmaxWidthheightAheightB	maxHeightdstMwarpedr   r   r   four_point_transform  s   ....6r   皙?r   rY   皙?Tc           (      C   s6  g g g g f\}}}	}
| D ]U}|d |d  t d|d |d   }|d |d  t d|d |d	   }tt|t||k rt|d |d |d |d	 g}t|d |d |d |d	 g}t|d |d |d |d g}t|d |d |d |d g}|||||d
||  || g qt j|d	 |d  |d |d  g}t j|d |d  |d |d  g}td| t|| }tt 	|d |d  t d|d |d   }tt 	|d |d  t d|d |d	   }|d t 
||  }|d t ||  }|d t 
||  }|d t ||  }|d t 
||  }|d t ||  }|d	 t 
||  }|d t ||  }|||g||g||g||gg q|rnt|dd d}g }|D ]U}t|dkr|d g} |d g}!|| qrtt |!|d  |t |  k r| |d  |!|d  || qr|d g} |d g}!|	| |g}qr|	| |	D ]F}"t|"dkr	|"d }#t|t|#d |#d  |#d  }|
|#d | |#d | |#d | |#d | g qt|"dd d}"g g }$}|"D ]a}#t|dkr1|#d g} |#d }||# qtt | |#d  |t |  k rg|#d | ||#d |#d   k rg| |#d  |#d }||# q|#d g} |#d }|$| |#g}qt|dkr|$| |$D ]}%t|%dkrt|%dd dd }t|%dd dd }t|%dd dd }t|%dd dd }|| }&|| }'t|t|&|' }|
|| || || || g q|%d }#|#d |#d  }&|#d |#d  }'t|t|&|' }|
|#d | |#d | |#d | |#d | g qq|
|fS )Nr&   r   
   r	   r   r      r'      r   g
ףp=
?c                 S   r-   )Nr'   r   r   r   r   r   r1     r2   z group_text_box.<locals>.<lambda>r3   c                 S   r-   r.   r   r   r   r   r   r1     r2   c                 S   r-   r.   r   r/   r   r   r   r1     r2   c                 S   r-   Nr   r   r/   r   r   r   r1     r2   c                 S   r-   )Nr	   r   r/   r   r   r   r1     r2   c                 S   r-   )Nr&   r   r/   r   r   r   r1     r2   )r   maximumr   absminr9   linalgr^   r   arctancossinr7   r   mean)(polys	slope_thsycenter_ths
height_ths	width_ths
add_marginsort_outputhorizontal_listr   combined_listmerged_listpolyslope_up
slope_downx_maxx_miny_maxy_minheightwidthmargintheta13theta24x1y1x2y2x3y3x4y4new_boxb_height	b_ycenterboxesbox
merged_boxmbox	box_width
box_heightr   r   r   group_text_box  s   
((    $((22$

&





"6

H


&6r(  c                 C   s   | | }|dk rd| }|S )zR
    Calculate aspect ratio for normal use case (w>h) and vertical text (h>w)
    rY   r   )r  r  ratior   r   r   calculate_ratio-  s   r*  c                 C   sj   || }|dk r!t ||}tj| |t|| ftjjd} | |fS tj| t|| |ftjjd} | |fS )z]
    Calculate ratio and resize correctly for both horizontal text
    and vertical case
    rY   )interpolation)r*  r   resizer   r   
ResamplingLANCZOS)imgr  r  model_heightr)  r   r   r   compute_ratio_and_resize6  s   
  r1  @   c                 C   s  g }|j \}}d\}}	|D ]?}
tj|
dd}t||}t|j d |j d }t|| }|dkr1qt||j d |j d |\}}||
|f t||	}	qt	
|	}	| D ]a}
td|
d }t|
d |}td|
d }t|
d |}|||||f }|| }|| }t||}t|| }|dkrqTt||||\}}|||g||g||g||gg|f t||}qTt	
|}t||	}t	
|| }|rt|dd	 d
}||fS )N)r   r   r   r   r   r   r	   r&   c                 S   s   | d d d S )Nr   r   r   r   r   r   r   r1   n  s    z get_image_list.<locals>.<lambda>r3   )r   r   r   r   r*  r   r1  r9   r   mathceilr   r7   )r  r   r/  r0  r  
image_list	maximum_y	maximum_xmax_ratio_horimax_ratio_freer#  r   transformed_imgr)  	new_widthcrop_imgr  r  r  r  r  r  	max_ratio	max_widthr   r   r   get_image_listD  sF   



&

r?  c                 C   sv   t j|d}|rtddddnd }t| ||d t|d}||| W d    n1 s/w   Y  t | d S )Nztemp.zip	Progress:Complete2   prefixsuffixr   
reporthookr   )ospathr   printProgressBarr
   r   extractremove)urlfilenamemodel_storage_directoryverbosezip_pathrG  zipObjr   r   r   download_and_unzipq  s   rS  c                    sb   t  }t| d t fdddD ]}|| qW d    | S 1 s(w   Y  | S )Nrbc                      s
     dS )Ni   )r   r   fr   r   r1   |  s   
 zcalculate_md5.<locals>.<lambda>    )hashlibmd5r   iterupdate	hexdigest)fnamehash_md5chunkr   rU  r   calculate_md5y  s   
r`  c                 C   s   t | t|  S rW   )r   r   )
input_listr   r   r   r     s   r   ltrc                    s  g }| D ];}dd |d D }dd |d D }t |}t|}	t |}
t|}||
 }||d ||	|
||d|
|  dg qd tdd |D dkrdd |D }t fd	d|D dkri |d d
< n fdd|D }tdd |D t dd |D |  }tdd |D |  }t dd |D |  }tdd |D |  }d}|D ]F}||d   ko|kn  p||d   ko|kn  }||d   ko|kn  p||d   ko|kn  }|r|r |d
< d} nq|dkr d7  tdd |D dksNg }tdd |D D ]fdd|D }tdd |D t dd |D }tdd |D }t dd |D }tdd |D }d}t|dkrt dd |D fd d|D }|d!krt d"d |D }|D ]}|d |kr|}qn|d#krtd$d |D }|D ]}|d |kr|}q|d%|d  7 }|| t|dks\|||g||g||g||gg|dd  g q|S )&Nc                 S      g | ]}t |d  qS r   r   r   coordr   r   r   r     r   z!get_paragraph.<locals>.<listcomp>r   c                 S   rc  r   rd  re  r   r   r   r     r   r   r   c                 S      g | ]
}|d  dkr|qS r   r   r   r   r#  r   r   r   r     r   c                 S   rg  rh  r   ri  r   r   r   r     r   c                       g | ]
}|d   kr|qS r   r   ri  current_groupr   r   r     r   r   c                    rj  rk  r   ri  rl  r   r   r     r   c                 S   r   r   r   ri  r   r   r   r     r   c                 S   r   r   r   ri  r   r   r   r     r   c                 S   r   r	   r   ri  r   r   r   r     r   c                 S   r   r&   r   ri  r   r   r   r     r   c                 S   r   r'   r   ri  r   r   r   r     r   Fr	   r&   r'   Tc                 s   s    | ]}|d  V  qdS )r   Nr   ri  r   r   r   	<genexpr>  s    z get_paragraph.<locals>.<genexpr>c                    rj  rk  r   ri  )rs   r   r   r     r   c                 S   r   r   r   ri  r   r   r   r     r   c                 S   r   r   r   ri  r   r   r   r     r   c                 S   r   rn  r   ri  r   r   r   r     r   c                 S   r   ro  r   ri  r   r   r   r     r   c                 S   r   rp  r   ri  r   r   r   r     r   r*   c                 S   r   )r   r   ri  r   r   r   r     r   c                    s$   g | ]}|d   d  k r|qS )r   g?r   ri  )highestmean_heightr   r   r     s   $ rb  c                 S   r   r   r   ri  r   r   r   r     r   rtlc                 S   r   rn  r   ri  r   r   r   r     r   rv   )r   r   r9   r   r   r   setrL  )
raw_resultx_thsy_thsr!   	box_groupr#  all_xall_ymin_xmax_xmin_ymax_yr  
box_group0current_box_groupmin_gxmax_gxmin_gymax_gyadd_boxsame_horizontal_levelsame_vertical_levelr$   rr   
candidates	most_leftbest_box
most_rightr   )rm  rr  rs   rs  r   get_paragraph  sz   (88



2r  r*   d      █c                    s    fdd}|S )a  
    Call in a loop to create terminal progress bar
    @params:
        prefix      - Optional  : prefix string (Str)
        suffix      - Optional  : suffix string (Str)
        decimals    - Optional  : positive number of decimals in percent complete (Int)
        length      - Optional  : character length of bar (Int)
        fill        - Optional  : bar fill character (Str)
        printEnd    - Optional  : end character (e.g. "", "
") (Str)
    c              	      sn   | | | }dt   d |d }t| }| d|   }td d| d| d d	d
 d S )Nz{0:.zf}r  -z |z| z% r*   )end)strformatr   print)count	blockSize	totalSizeprogresspercentfilledLengthbardecimalsfillr   rD  rE  r   r   progress_hook  s
   (z'printProgressBar.<locals>.progress_hookr   )rD  rE  r  r   r  r  r   r  r   rJ    s   rJ  c                 C   s  t | tkr?| ds| dr*t| tddddd\}}t|tj}t	| nt| tj}tj
| } t| }||fS t | tkret| tj}t|tj}t|tj}t|tj}||fS t | tjkrt| jdkr| }t| tj}||fS t| jd	kr| jd d
krt| }t|tj}||fS t| jd	kr| jd d	kr| }t| tj}||fS t| jd	kr| jd dkr| d d d d d d	f }t|tj}t|tj}||fS t | tjkrt| }t|tj}t|tj}||fS td)Nzhttp://zhttps://r@  rA  rB  rC  rF  r	   r&   r   r'   zTInvalid input type. Supporting format = string(file path or url), bytes, numpy array) typer  
startswithr
   rJ  r   imreadIMREAD_GRAYSCALErH  rL  rI  
expanduserr   bytesr   
frombufferuint8imdecodeIMREAD_COLORcvtColorCOLOR_BGR2RGBCOLOR_BGR2GRAYndarrayr   r   COLOR_GRAY2BGRsqueezeCOLOR_RGB2BGRr   JpegImageFiler   
ValueError)r   tmpr\   img_cv_greyr/  nparrimage_arrayr   r   r   reformat_input  sN   

r  c                 C   s   t | tjrt| jdkst | treg g }}| D ]*}t|\}}|dur9|dur9t|||f}t|||f}|	| |	| qt
|t
|}}t|jdkrat|jdkratd||fS t| \}}||fS )a/  
    reformats an image or list of images or a 4D numpy image array &
    returns a list of corresponding img, img_cv_grey nd.arrays
    image:
        [file path, numpy-array, byte stream object,
        list of file paths, list of numpy-array, 4D numpy array,
        list of byte stream objects]
    r'   Nr   zThe input image array contains images of different sizes. Please resize all images to same shape or pass n_width, n_height to auto-resize)
isinstancer   r  r   r   r   r  r   r,  r9   r   r  )r   n_widthn_heightr/  r  
single_imgclrgryr   r   r   reformat_input_batched  s   $	

r  c           
      C   sl   |d d  }d}| D ])}|D ]$}t j|d |dd}|j\}}t||}	t||	}||d |f qq
|S )Nr   T)reshaper   )r   rotater   r*  r   r9   )
rotationInfoimg_listresult_img_listr=  angleimg_inforotatedr  r  r)  r   r   r   make_rotated_img_list"  s   


r  c                    s\   g }t td D ]! t fddt tD dd dd }||    q
|S )a{   Select highest confidence augmentation for TTA
    Given a list of lists of results (outer list has one list per augmentation,
    inner lists index the images being recognized), choose the best result 
    according to confidence level.
    Each "result" is of the form (box coords, text, confidence)
    A final_result is returned which contains one result for each image
    r   c                    s    g | ]}||   d  fqS rn  r   )r   row_ixcol_ixresultsr   r   r   ?  r   z.set_result_with_confidence.<locals>.<listcomp>c                 S   r-   r   r   r/   r   r   r   r1   @  r2   z,set_result_with_confidence.<locals>.<lambda>r3   )r   r   r   r9   )r  final_resultbest_rowr   r  r   set_result_with_confidence3  s   r  )r   r   r   )r   r   r   rY   r   T)r2  T)T)r   r   rb  )r*   r*   r   r  r  )NN)2
__future__r   r   picklenumpyr   r3  r   PILr   r   scipyr   rX  sysrH  zipfiler   imgprocr   version_infosix.moves.urllib.requestr
   urllib.requestr%   rF   rG   rV   r   r   r   r   r   objectr   r   r   r(  r*  r1  r?  rS  r`  r   r  rJ  r  r  r  r  r   r   r   r   <module>   sP    
  '


'\q*
k	

-

E
(